0
class Foo{};

class BarParent
{
    Foo* p_foo;

    public:
    BarParent(Foo * const p_x) //OR BarParent(Foo const * x) OR BarParent(Foo * x)
                             //OR (Foo const * const x)
    {
        p_foo = x;
    }
};


class BarChild: public BarParent
{
    public:
    BarChild(const Foo& x)
    : BarParent(& x){}
};

我的意图是:在使用ctor时指向xwith 。有没有办法这样做。p_fooBarChild

我已经为BarParentctor 尝试了所有可能的签名,但没有运气。

摘要:由于某种原因,我混淆了将(指向非const对象的指针)const)打破const限制的事实。

4

3 回答 3

3

我为您提供两种选择:

  1. 要么您真的希望BarChild构造函数采用 a const Foo&,在这种情况下,您需要坚持您永远不会允许Foo修改对象的承诺。为此,两者p_x和都p_foo必须是const Foo*(即指向 的指针const Foo)。如果它是指向非的指针const Foo,那么您将有效地允许修改对象,从而违反您的承诺。

    class BarParent
    {
        const Foo* p_foo;
    
        public:
        BarParent(const Foo* p_x)
        {
            p_foo = x;
        }
    };
    
  2. 或者,您确实想保留 aFoo*而不是 a const Foo*,因此BarChild构造函数应该采用 aFoo&而不是 a const Foo&。这样,您就不会在保留 object 方面撒谎const

    class BarChild: public BarParent
    {
        public:
        BarChild(Foo& x)
        : BarParent(& x){}
    };
    
于 2013-04-02T20:55:27.383 回答
2

您误解了 aconst Foo&是什么。

Aconst Foo&是对变量的别名或引用,您永远无法通过该变量对其进行修改(不使用const_cast或 C 风格的强制转换)。这不仅仅是“现在”不修改它的承诺,而且还承诺你告诉这个变量的每个人都不会修改它。

如果你想存储一个指向这个数据的指针以便以后修改它,你不应该把它当作一个const Foo&,而是一个Foo&

所以要修复你的代码,重写BarChild如下:

class Foo{};

class BarParent
{
  Foo* p_foo;

  public:
    BarParent(Foo * p_x):
      p_foo(p_x)
    {}
};

class BarChild: public BarParent
{
  public:
  BarChild(Foo& x):
    BarParent(& x)
  {}
};
于 2013-04-02T20:58:20.240 回答
1

您可以使用以下方法抛弃 const-ness const_cast

p_foo = const_cast<Foo *>x;

但这通常是一个坏主意,原因有两个:

  • const 正确性的全部意义在于记录/强制执行关于谁可以修改什么的某些期望。 const_cast颠覆了这一点。

  • 在某些情况下,您甚至可能会释放未定义的行为(即,修改实际上是const通过非const指针的底层对象)。

一般来说,首先要找到一种避免需要这样做的方法(我无法提出任何具体建议,因为我不知道您的用例是什么)。

于 2013-04-02T20:40:54.207 回答