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&
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.
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.
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.