The following will compile even though a const member function will modify the value of a member. How so ?
#include <iostream>
struct foo
{
std::string &str;
foo(std::string &other) : str(other) {}
void operator()(std::string &some) const
{
str += some;
}
};
int main()
{
std::string ext("Hello");
foo a{ ext };
std::string more(" world!");
a(more);
cout << a.str;
return 0;
}
The const
qualifier of a class member function indicates that this member function (e.g., foo::operator() const
) cannot change the state of the object from the client's point of view (i.e., it's abstract state). This is not exactly the same as saying that the object's raw bits are not going to change.
It is forbitten to C++ compilers to consider objects as raw bits, unless they can resolve the problem of aliasing. which in your case the compiler cannot. This is due to the fact that a non-constant alias exists (i.e., std::string &str
) and consequently the state of the object is modifiable.
That is, calling operator()
on object a
does not change the state of a
(i.e., although ext
has changed, the str
still remains an alias of ext
).
The above also explains why pointing at an object with a pointer to constant (i.e., std::string * const str
) does not guarantee that the object won't be modified. It only guarantees that the object won't change through that pointer.
Consider the reference like a classic pointer:
#include <iostream>
struct foo
{
std::string * const str; // is the same as std::string &str
foo(std::string &other) : str(&other) {}
void operator()(std::string &some) const
{
*str += some;
}
};
int main()
{
std::string ext("Hello");
foo a{ ext };
std::string more(" world!");
a(more);
cout << a.str;
return 0;
}
You'll see that the pointer doesn't change, only the value pointed by it does.
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