委托给removeAll()的方法的const指针参数

时间:2010-08-31 22:08:04

标签: c++ const-correctness

考虑这样的方法:

void Parent::removeChild(Child *child)
{
    children.removeAll(child);
}

在这种情况下,由于永远不会自行修改,因此可以将其作为const指针。但由于 children 属于QList类型,因此removeAll()接受对非const 指针的const引用。

处理此问题的推荐方法是什么?跳过方法参数的constness或 const_cast const指针以适应removeAll()方法?

3 个答案:

答案 0 :(得分:1)

棘手的一个。您应该添加更多代码,但是从docs我假设您有QList<Child*>并且无法将其更改为QList<const Child*>,因为您需要访问非{0}中的实际对象const方式。

由于removeAll()函数的所有功能都是删除列表中的条目,并且它决不会修改指向的Child(它怎么可能,它对Child类一无所知)它会在这里安全使用const_cast

答案 1 :(得分:0)

如果你想要的是说更改子列表不是父实例的更改,那么只需创建子列表mutable

但是,请确保它真的是您想要的语义父类。如果孩子不属于父状态(在你的系统的语义中),那么应该没问题。如果它是Parent实例状态的一部分,那么你应该保留一个非const成员函数。

mutable关键字适用于特殊情况,其中不应将类的成员视为实例的状态,只是附加信息。如果是你的情况,那就使用它。

否则,让你的成员函数为非const,因为它修改了父成员。

答案 2 :(得分:0)

看起来QList设计用于非指针。他们定义了很多const为const T&的接口,如果QListChild上,而不是Child*,那么该接口会很有效。

它可以很好地处理指针,但它不能为它们声明constness。我不建议将你的QList更改为Child,除非复制成本低,你有复制ctor,dtor,op =,op ==等所有正确的语义,你不介意在列表中有副本而不是您传入的对象。您可以看到int或字符串如何按预期工作(removeAll将是const正确的。)

如果const正确性对您很重要,那么使用const_cast。然后声明一个const ref并传入它。

void Parent::removeChild(const Child *child)
{
    QList<Child*>::const_reference constRefToChild = const_cast<Child *> child;
    children.removeAll(constRefToChild);
}

这一点是,如果removeAll被更改为不接受const,则会出现编译器错误。然后你就会知道removeAll不保留参数的常量。