static_cast从base到派生在这个特定的上下文中被认为是“安全的”吗?

时间:2014-06-15 12:30:37

标签: c++ static-cast

在多态层次结构对象树中,只有Root类型实例具有null _parent。我正在使用此方法来获取特定树节点的根对象:

inline Root * root() {
    Object * r = this;
    while (r->_parent) r = r->_parent;
    return static_cast<Root *>(r);
}

我一直在阅读从基础到派生的静态转换通常不被认为是安全的,但是我的特定情况如何Root {null {{ 1}}?

2 个答案:

答案 0 :(得分:1)

如果您知道r属于Root类型,则静态强制转换是完全安全的。实际上,编译器允许您在此上下文中使用static_cast的唯一原因是RootObject兼容。如果您使用两种不兼容的类型进行尝试,则会产生编译器错误 - 在这种情况下需要reinterpret_cast

答案 1 :(得分:1)

只要您的不变量成立,它就是安全的。但是,大部分大型代码库强制执行的不变量很少保持不变。

至少,我会在这里插入Assert(dynamic_cast<...>(...)),并在每个位置parent被修改,以试图在调试中强制执行不变量。

另一种方法是公开virtual Root* as_root(),只返回nullptr中的非Root。这比(大多数)static_cast更昂贵,但将演员逻辑放在一个可搜索的中心位置。很少有这种virtual电话是您的计划的瓶颈。

更有趣的是'如果找不到Root,你会怎么做?可能返回nullptr,这意味着在所有调用站点处理它,至少在调试Assert级别。如果假定呼叫站点不处理它,则返回Root&,并在调试中调用终止/退出(在Assert之后)(如果在那里检查,则在发布/通知/之后释放)等)。