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){}
};
我打算:在使用x
ctor时,使用p_foo
指向BarChild
。有没有办法这样做。
我已经为BarParent
ctor尝试了所有可能的签名而没有运气。
摘要: 出于某种原因,我混淆了将(指向非const
对象的指针)分配给({{1的指针)的事实对象)打破const
限制。
答案 0 :(得分:3)
我向您介绍两种选择:
要么你真的希望BarChild
构造函数采用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;
}
};
或者,您确实希望保留Foo*
而不是const Foo*
,因此BarChild
构造函数应该使用Foo&
而不是const Foo&
const
。这样,您就不会说谎保留对象class BarChild: public BarParent
{
public:
BarChild(Foo& x)
: BarParent(& x){}
};
。
{{1}}
答案 1 :(得分:2)
您误解了const Foo&
是什么。
const 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)
{}
};
答案 2 :(得分:1)
你可以用const_cast
:
p_foo = const_cast<Foo *>x;
但这通常是一个坏主意,原因有两个:
const-correctness的重点是记录/强制执行某些关于谁可以修改内容的期望。 const_cast
颠覆了这一点。
在某些情况下,您甚至可以释放未定义的行为(即,通过非const
指针修改真正为const
的基础对象)。
一般来说,找到一种方法来避免首先需要这样做(我不能提出任何具体的建议,因为我不知道你的用例是什么)。