我对const版本和非const版本成员函数非常困惑,如下所示:
value_type& top() { return this.item }
const value_type& top() const { return this.item }
这两个功能有什么区别?他们会在什么情况下使用?
答案 0 :(得分:16)
简而言之,他们习惯于为你的程序添加'const correctness'。
value_type& top() { return this.item }
这用于提供对item
的可变访问。它被使用,因此您可以修改容器中的元素。
例如:
c.top().set_property(5); // OK - sets a property of 'item'
cout << c.top().get_property(); // OK - gets a property of 'item'
此模式的一个常见示例是使用vector::operator[int index]
返回对元素的可变访问。
std::vector<int> v(5);
v[0] = 1; // Returns operator[] returns int&.
另一方面:
const value_type& top() const { return this.item }
这用于提供对const
的{{1}}访问权限。它比以前的版本更具限制性 - 但它有一个优点 - 你可以在const对象上调用它。
item
按照矢量示例:
void Foo(const Container &c) {
c.top(); // Since 'c' is const, you cannot modify it... so the const top is called.
c.top().set_property(5); // compile error can't modify const 'item'.
c.top().get_property(); // OK, const access on 'item'.
}
答案 1 :(得分:6)
如果在const限定的对象上调用成员函数,则将调用const限定的成员函数。
如果在非const限定的对象上调用成员函数,则将调用非const限定的成员函数。
例如:
MyStack s;
s.top(); // calls non-const member function
const MyStack t;
t.top(); // calls const member function
请注意,在对对象的引用上调用成员函数或通过指向对象的指针时,适用相同的规则:如果指针或引用是const对象,则将调用const成员函数;否则将调用非const成员函数。
答案 2 :(得分:4)
如果你有
class Foo
{
value_type& top() { return this.item }
const value_type& top() const { return this.item }
}
如果你有
Foo foo;
const Foo cfoo;
致电top()
时的退货类型如下:
value_type& bar = foo.top();
const value_type& cbar = cfoo.top();
换句话说 - 如果你有一个类的常量实例,则选择函数的const版本作为调用的重载。
这个(在这种特殊情况下)的原因是你可以从类的const实例中提供对成员的引用(在本例中为item
),并确保它们也是const - 因此无法修改,因此保留了它们来自实例的常量。
答案 3 :(得分:0)
当成员函数声明为const
时,发生的事情是传递给函数的隐式this
指针参数被输入为指向const对象的指针。这允许使用const对象实例调用函数。
value_type& top(); // this function cannot be called using a `const` object
const value_type& top() const; // this function can be called on a `const` object
答案 4 :(得分:0)
value_type& top() { return this.item; }
确保可以修改调用对象的数据成员或返回值。
value_type& top() const { return this.item; }
确保无法修改调用对象的数据成员,但返回值可以是。因此,例如,如果我执行value_type item_of_x = x.top();
,则可以修改item_of_x
,但x
不能修改this.item = someValue;
。否则,会发生编译器错误(例如在函数体内部有代码const value_type& top() { return this.item; }
)。
const value_type item_of_x = x.top();
确保允许修改调用对象的数据成员,但返回值不能。它与上面讨论的相反:如果我执行item_of_x
,x
无法修改,value_type item_of_x = x.top();
可以修改。item_of_x
注意 item_of_x
仍允许修改const value_type& top() const { return this.item; }
,因为Parallel.ForEach()
现在是非常量的。
StaTaskScheduler
确保既不能修改调用对象的数据成员也不能修改返回值。