The following code calls a const
method passing a reference to a member, which is then modified.
#include <iostream>
struct A {
int i;
A(int _x) : i(_x) { }
void calc(int& j, const int value) const { j = value; }
void set1() { calc(i, 1); }
};
int main()
{
A a(3);
std::cout << a.i << std::endl;
a.set1();
std::cout << a.i << std::endl;
return 0;
}
The code compiles with gcc 6.4.0, and with clang 5.0.2, with no warnings.
Is the code legal?
The const
method calc
is able to modify the object, when called from a non-const
method.
A reference with const is useful when you need to pass an object in the function without making a copy of the object with the guaranty that function will not change anything to passed object. It will save your stack memory and good thing is that you can also pass a non-const object to the function.
See the below code, where I am assigning the const object to the ordinary reference and printing their value. error: binding ‘const int’ to the reference of type ‘int&’ discards qualifiers. A CV-qualified reference can refer to an ordinary object (not qualified by CV). It means a reference to const can refer to a non-const object.
Although instantiating const class objects is one way to create const objects, a more common way to get a const object is by passing an object to a function by const reference. In the lesson 11.3 -- Passing arguments by reference, we covered the merits of passing class arguments by const reference instead of by value.
In C++ you can write reference to const in two ways. For example, if I need to create a reference to const integer then I can write the expression in two ways. Most programmers like the first expression. Note: Reference to const means that reference itself could not modify the referred object.
const
qualifier on a member function applies to the *this
instance.
In calc()
, this
is a pointer to const A
, but the parameter j
is taken by non-const reference, so this is perfectly standard behaviour.
Now, if in calc
you tried to assign to this->i
, the code would not compile.
void A::calc(const int value) const
{
i = value; // Compilation error here: i is a data member of a const instance
}
In the same way, if set1
was made a const member function, then, the code would not compile (because it would try to bind this->i
to a parameter taken by non-const reference)
Sure. Marking the method const
just makes *this
const
, i.e. the function promises not to modify the object by writing through this
.
It's still possible to modify the object through other means (assuming they're not marked const
as well, such as int& j
in your example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With