Alex
Alex

Reputation: 73

C++ const method on non const pointer member

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

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 pointed from his method? After many research on web, no satisfied reponse found yet.

Thanks for your help.

Upvotes: 7

Views: 1034

Answers (4)

Sam Varshavchik
Sam Varshavchik

Reputation: 118300

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.

Upvotes: 2

Igor Tandetnik
Igor Tandetnik

Reputation: 52471

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.

Upvotes: 11

rwols
rwols

Reputation: 3078

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.

Upvotes: 6

R Sahu
R Sahu

Reputation: 206567

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;
}

Upvotes: 7

Related Questions