Dmitry Paliy
Dmitry Paliy

Reputation: 88

How to make object by pointer in const object constant?

class Foo {
public:
    int a = 1;
};

class Bar {
public:
    Foo *foo_ptr = new Foo;
};

int main() {
    const Bar bar;
    bar.foo_ptr.a++;        //   valid: a == 2
    bar.foo_ptr = nullptr;  // invalid: foo_ptr is const
}

I understand, why code above is correct - object bar is constant, so foo_ptr is constant pointer to a non-const Foo object. But I think it's a bit illogical. Why Foo object also did not become const?

What should I do, if I want Bar object to become absolute const here, and the foo_ptr to be a constant pointer to a constant object?

For example, I send Bar object to some method, and I don't want it or any Foo objects in it to be modifiable.

Upvotes: 1

Views: 305

Answers (2)

Jarod42
Jarod42

Reputation: 218098

In your case, you might use value instead of pointer:

class Bar {
public:
    Foo foo;
};

then bar.foo would be const when bar is

If you really need "pointer", you might use std::experimental::propagate_const

class Bar {
public:
    std::experimental::propagate_const<Foo*> foo_ptr = new Foo; // work also with smart pointers
};

Demo

Upvotes: 1

R Sahu
R Sahu

Reputation: 206717

But I think it's a bit illogical. Why Foo object also did not become const?

The compiler cannot assume how far to extend the notion of const. You, as the designer of Bar, have to help the compiler with that. You can do that by making the member variable private and providing public interfaces that preserve the const-ness of the object that the pointer points to.

Update your class to:

class Bar {
   public:
      Foo* getFoo();
      Foo const* getFoo() const;

   private:
      Foo *foo_ptr = new Foo;
};

and now

int main() {

    const Bar bar1;
    bar1.getFoo()->a++;  // Not OK. Compiler error.

    Bar bar2;
    bar2.getFoo()->a++;  // OK.
}

Upvotes: 4

Related Questions