const成员函数和非const成员函数之间有什么区别?

时间:2010-06-18 02:22:30

标签: c++

我对const版本和非const版本成员函数非常困惑,如下所示:

value_type& top() { return this.item }
const value_type& top() const { return this.item }

这两个功能有什么区别?他们会在什么情况下使用?

5 个答案:

答案 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_xx无法修改,value_type item_of_x = x.top();可以修改。item_of_x 注意 item_of_x仍允许修改const value_type& top() const { return this.item; },因为Parallel.ForEach()现在是非常量的。

StaTaskScheduler确保既不能修改调用对象的数据成员也不能修改返回值。