当一个方法只接受 Foo *const 时,我应该const_cast "this"吗?

Should I const_cast "this" when a method only accepts Foo *const?

本文关键字:const 我应该 cast this Foo 一个 方法      更新时间:2023-10-16

我有一个类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文档传递,这在我的场景中解析为Foo *const &value

为了让我的getPosition()方法调用我自己的indexOf()方法,为了从const方法传递this,需要至少有const Foo *child的签名。(因为这是const Foo *const).

我的代码不会编译,但是const Foo *const child不能为QList::indexOf转换为Foo *const child。我的两个方法都没有修改对象状态,所以它们应该是const的(也就是说,我不想取消getPosition的成本来接收一个非const的this)。

所以问题是,我如何从this在const上下文中(const Foo *const)到QList::indexOf所需要的。既然我知道我的indexOf(以及随后的调用)不会改变它,我应该在getPosition中常量转换this吗?

还有什么我应该做的吗?也许我的设计有问题。

我认为这是const_cast的一个完全合理的用例,但是它不是this,你需要const_cast,但child。在这种情况下,QList::indexOf期望一个指向Foo (Foo* const)的常量指针,但child是一个指向Foo (const Foo* const)的常量指针。没有从Foo* constconst Foo* const的隐式转换,因为这将从所指向的值中删除const-ness。

那么,为了修复你的代码,我将把这行改为

return children.indexOf(const_cast<Foo*>(child));

你知道QList::indexOf不会修改任何child指向的,所以这不会产生未定义的行为。然而,我还是要加一条评论,解释为什么const_cast是必要的。