C++ const method on non const pointer member

后端 未结 4 1069
礼貌的吻别
礼貌的吻别 2020-12-19 10:33

I was wondering how protect a non const pointer member from an object throught a const method. For example:

class B{
    public:
        B(){
            thi         


        
相关标签:
4条回答
  • 2020-12-19 10:53

    Try using the following general approach, to protect the const-ness of objects referenced via pointers, in this situation.

    1. Rename B *b

      B *my_pointer_to_b;
      

      And change the initialization in the constructor accordingly.

    2. Implement two stubs:

      B *my_b() { return b; }
      const B *my_b() const { return b; }
      
    3. 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.

    0 讨论(0)
  • 2020-12-19 11:03

    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.

    0 讨论(0)
  • 2020-12-19 11:06

    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;
    }
    
    0 讨论(0)
  • 2020-12-19 11:11

    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.

    0 讨论(0)
提交回复
热议问题