我有一个类Foo
,它是一个自引用树状结构(最低限度):
class Foo {
public:
// Gets this child's position relative to it's parent.
int getPosition() const {
return parent->indexOf(this);
}
int indexOf(const Foo *const child) const {
return children.indexOf(child); // this line causes an error.
}
private:
Foo *parent;
QList<Foo *> children;
}
行return children.indexOf(child)
期望const T &value
根据QList docs传递Foo *const &value
,对于我的方案,这会解析为getPosition()
。
为了让我的indexOf()
方法调用我自己的const Foo *child
方法,需要至少有this
的签名才能从const传递const Foo *const
方法。 (因为这是const Foo *const child
)。
我的代码无法编译,因为Foo *const child
无法转换为QList::indexOf
getPosition
。我的方法都没有修改对象状态,因此它们应该是const(即我不想取消this
来接收非const this
)。
所以问题是,我如何从const上下文中的const Foo *const
(QList::indexOf
)转到this
所需的内容。我应该在getPosition
内进行常规indexOf
,因为我知道我的{{1}}(及后续调用)不会改变它吗?
还有别的我应该做的吗?也许我的设计有问题。
答案 0 :(得分:5)
我认为const_cast
这是一个非常合理的用例,但是this
不是const_cast
,而是child
。QList::indexOf
。在这种情况下,Foo
需要指向Foo* const
(child
)的常量指针,但Foo
是指向常量const Foo* const
的常量指针(Foo* const
})。没有从const Foo* const
到return children.indexOf(const_cast<Foo*>(child));
的隐式转换,因为这会从指向的值中删除常量。
因此,要修改代码,我会将行更改为
QList::indexOf
您知道child
不会修改任何const_cast
点,因此不会产生未定义的行为。但是,我会添加一条评论,解释为什么{{1}}是必要的。