开发者

What's the difference between a const member function and a non-const member function?

开发者 https://www.devze.com 2023-01-04 02:04 出处:网络
I am very confused about the const version and non-const version member function like below: value_type& top() { return this.item }

I am very confused about the const version and non-const version member function like below:

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

What is the difference between these two functions? In wh开发者_如何学Cat situation would they be used?


In short, they're used to add 'const correctness' to your program.

value_type& top() { return this.item }

This is used to provide mutable access to item. It is used so you can modify the element in the container.

For example:

c.top().set_property(5);  // OK - sets a property of 'item'
cout << c.top().get_property();  // OK - gets a property of 'item'

One common example for this pattern is returning mutable access to an element with vector::operator[int index].

std::vector<int> v(5);
v[0] = 1;  // Returns operator[] returns int&.

On the other hand:

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

This is used to provide const access to item. It's more restrictive than the previous version - but it has one advantage - you can call it on a const object.

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'. 
}

To follow the vector example:

const std::vector<int> v(5, 2);
v[0] = 5;  // compile error, can't mutate a const vector.
std::cout << v[1];  // OK, const access to the vector.


The const-qualified member function will be called if the member function is called on an object that is const-qualified.

The non-const-qualified member function will be called if the member function is called on an object that is not const-qualified.

For example:

MyStack s;
s.top(); // calls non-const member function

const MyStack t;
t.top(); // calls const member function

Note that the same rules apply when calling a member function on a reference to an object or through a pointer to an object: if the pointer or reference is to a const object, the const member function will be called; otherwise the non-const member function will be called.


If you have

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

If you have

Foo foo;
const Foo cfoo;

The return types when you call top() are as follows:

value_type& bar = foo.top();
const value_type& cbar = cfoo.top();

In other words - if you have a constant instance of your class, the const version of the function is chosen as the overload to call.

The reason for this (in this particular case) is so that you can give out references to members (like item in this case) from a const instance of a class, and ensure that they too are const - thus unmodifiable and therefore preserving the const-ness of the instance they came from.


When member function is declared as const what's happening is that the implicit this pointer parameter passed to the function is typed to be a pointer to a const object. This allows the function to be called using a const object instance.

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


value_type& top() { return this.item; } ensures that either the calling object's data members can be modified or the return value can be.

value_type& top() const { return this.item; } ensures that the calling object's data members can't be modified, but the return value can be. So, for example, if I perform value_type item_of_x = x.top();, item_of_x can be modified but x cannot. Otherwise, a compiler error occurs (such as having the code this.item = someValue; inside of the function body).

const value_type& top() { return this.item; } ensures that the calling object's data members are allowed to be modified, but the return value cannot be. It's the opposite of what is discussed above: if I perform const value_type item_of_x = x.top();, item_of_x can't be modified but x can. NOTE value_type item_of_x = x.top(); still allows for modification of item_of_x, as item_of_x is now non-const.

const value_type& top() const { return this.item; } ensures that neither the calling object's data members can be modified nor the return value can be.

0

精彩评论

暂无评论...
验证码 换一张
取 消