I am trying to understand c++'s const
semantics more in depth but I can't fully understand what really the constness guarantee worth is.
As I see it, the constness guarantees that there will be no mutation, but consider the following (contrived) example:
#include <iostream>
#include <optional>
#include <memory>
class A {
public:
int i{0};
void foo() {
i = 42;
};
};
class B {
public:
A *a1;
A a2;
B() {
a1 = &a2;
}
void bar() const {
a1->foo();
}
};
int main() {
B b;
std::cout << b.a2.i << std::endl; // output is 0
b.bar();
std::cout << b.a2.i << std::endl; // output is 42
}
Since bar
is const
, one would assume that it wouldn't mutate the object b
. But after its invocation b
is mutated.
If I write the method foo
like this
void bar() const {
a2.foo();
}
then the compiler catches it as expected.
So it seems that one can fairly easily circumvent the compiler with pointers. I guess my main question is, how or if I can be 100% sure that const
methods won't cause any mutation to the objects they are invoked with? Or do I have completely false expectations about const
?
Why does c++ allow invocation of non-const methods over pointers in const
methods?
EDIT:
thanks to Galik's comment, I now found this:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4372.html
Well, this was exactly what I was looking for! Thanks! And I find Yakk's answer also very helpful, so I'll accept his answer.