1
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.

10
  • Regarding the pointer class member variable, mutable might come in handy. Commented Jul 25, 2018 at 18:20
  • @πάνταῥεῖ, I think the dupe does not address the OP's concern. I think they want to be able to use bar.foo_ptr.a++; when bar is not const while disallowing it when bar is const. Commented Jul 25, 2018 at 18:29
  • @RSahu I believe such could be done providing appropriate getter/setter functions varying from the instances const nature, instead of just making the raw pointer member variable public. Anyways understanding the difference of a const pointer vs a pointer to a const object lays out the basis knowledge, how to implement such. Commented Jul 25, 2018 at 18:35
  • @πάνταῥεῖ, exactly. They need appropriate public functions and not expose the pointer as a public member variable. Understanding const pointer vs pointer to const object is necessary but that does not necessarily help with their objective, assuming we, including the OP, are on the same page on the objective. Commented Jul 25, 2018 at 18:39
  • 1
    well, it behaves exactly as you defined it. if you do not want foo changed, make it const. btw: you are leaking memory. Stop using owning raw pointers. Commented Jul 25, 2018 at 18:51

2 Answers 2

4

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.
}
Sign up to request clarification or add additional context in comments.

2 Comments

use a std::unique_ptr for "foo_ptr" to prevent it leaking memory :)
@skeller, or not use pointers for these silly objects at all. The crux of my post is to show how to define the notion of const for a user defined type and not get that diluted by other concerns.
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.