I was wondering how protect a non const pointer member from an object throught a const method. For example:
class B{
public:
B(){
thi
Try using the following general approach, to protect the const-ness of objects referenced via pointers, in this situation.
Rename B *b
B *my_pointer_to_b;
And change the initialization in the constructor accordingly.
Implement two stubs:
B *my_b() { return b; }
const B *my_b() const { return b; }
Replace all existing references to b with my_b(), in the existing code. Going forward, in any new code, always use my_b() to return the pointer to b.
Mutable methods will get a non-const pointer to B; const methods will get a const pointer to B, and the extra step of renaming makes sure that all existing code is forced to comply with the new regime.
The problem you have is that a const
method makes all the member variables const
. In this case however, it makes the pointer const
. Specifically, it's as if all you have is B * const b
, which means a constant pointer to a (still) mutable B
. If you do not declare your member variable as const B * b
, (that is, a mutable pointer to a constant B
), then there is no way to protect from this behavior.
If all you need is a const B
, then by all means, define A
like this:
class A {
public:
A() : b(new B) {}
// This WILL give an error now.
void changeMemberFromConstMethod() const { b->setVal(); }
private:
const B* b;
}
However, if other methods of A
mutate B
, then all you can do is make sure that B
does not get mutated in your const
methods of A
.
If you change the member of A
from
B* b;
to
B b;
then you will get the expected behavior.
class A{
public:
A() : b() {}
void changeMemberFromConstMethod() const{
this->b.setVal(); // This will produce a compiler error.
}
private:
B b;
}
Something like this, perhaps:
template <typename T>
class deep_const_ptr {
T* p_;
public:
deep_const_ptr(T* p) : p_(p);
T* operator->() { return p_;}
const T* operator->() const { return p_;}
};
class A {
deep_const_ptr<B> b = new B;
};
deep_const_ptr
behaves like a const T* const
pointer in A
's const methods, and like T*
in non-const methods. Fleshing the class out further is left as an exercise for the reader.