如何通过const对象中的指针使对象恒定?

时间:2018-07-25 18:15:24

标签: c++ pointers const transitive-const

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
}

我知道,为什么上面的代码正确-对象bar是常量,所以foo_ptr是指向非常量Foo对象的常量指针。但是我认为这有点不合逻辑。为什么Foo对象也没有变成const?

如果我希望Bar对象在这里成为绝对const,并且foo_ptr是指向常量对象的常量指针,该怎么办?

例如,我将Bar对象发送给某种方法,但我不希望它或其中的任何Foo对象可修改。

2 个答案:

答案 0 :(得分:3)

  

但是我认为这有点不合逻辑。为什么Foo对象也没有变成const

编译器无法假设将const的概念扩展多远。作为Bar的设计者,您必须为此提供帮助。您可以通过使成员变量private并提供public接口来保留指针所指向的对象的const型来做到这一点。

将您的课程更新为:

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

   private:
      Foo *foo_ptr = new Foo;
};

现在

int main() {

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

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

答案 1 :(得分:1)

在这种情况下,您可以使用值代替指针:

class Bar {
public:
    Foo foo;
};

然后,bar.foobar时将为

如果您确实需要“指针”,则可以使用std::experimental::propagate_const

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

Demo