C ++ const method for non-constant pointer

I was wondering how to protect a non-const pointer from an object through the const method. For instance:

class B{ public: B(){ this->val=0; } void setVal(){ this->val = 2; } private: int val; }; class A{ public: A():b(new B){} void changeMemberFromConstMethod() const{ this->b->setVal(); } private: B * b; // how to protect data pointed in A::changeMemberFromConstMethod } 

Is it possible to "protect" A :: b data from its method? After many studies on the Internet, a satisfied answer has not yet been found.

Thanks for your help.

+5
source share
4 answers

Something like this is possible:

 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 as a pointer to const T* const in A const methods and as T* in non-constant methods. Further delineation of the class is left as an exercise for the reader.

+10
source

If you change element A with

  B* b; 

to

  B b; 

then you get the expected behavior.

 class A{ public: A() : b() {} void changeMemberFromConstMethod() const{ this->b.setVal(); // This will produce a compiler error. } private: B b; } 
+6
source

The problem is that the const method does all const member variables. In this case, however, it makes a const pointer. In particular, 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 a member variable as const B * b (i.e., a mutable pointer to constant B ), then there is no way to protect this behavior.

If you only need const B , then be sure to specify A as follows:

 class A { public: A() : b(new B) {} // This WILL give an error now. void changeMemberFromConstMethod() const { b->setVal(); } private: const B* b; } 

However, if the other methods are A mutate B , then all you can do is make sure that B does not have a mutation in your const A methods.

+4
source

Try the following general approach to protect the constant of the objects referenced by pointers in this situation.

  • Rename B * b

     B *my_pointer_to_b; 

    And accordingly change the initialization in the constructor.

  • Insert two stubs:

     B *my_b() { return b; } const B *my_b() const { return b; } 
  • Replace all existing references to b with my_b () in existing code. In any new code, always use my_b () to return a pointer to b.

Variable methods will receive a non-constant pointer to B; const methods will get a const pointer to B, and an additional renaming step ensures that all existing code is forced to conform to the new mode.

+1
source

Source: https://habr.com/ru/post/1201448/


All Articles