在多态层次结构对象树中,只有Root
类型实例具有null
_parent
。我正在使用此方法来获取特定树节点的根对象:
inline Root * root() {
Object * r = this;
while (r->_parent) r = r->_parent;
return static_cast<Root *>(r);
}
我一直在阅读从基础到派生的静态转换通常不被认为是安全的,但是我的特定情况如何Root
{null
{{ 1}}?
答案 0 :(得分:1)
如果您知道r
属于Root
类型,则静态强制转换是完全安全的。实际上,编译器允许您在此上下文中使用static_cast
的唯一原因是Root
和Object
兼容。如果您使用两种不兼容的类型进行尝试,则会产生编译器错误 - 在这种情况下需要reinterpret_cast
。
答案 1 :(得分:1)
只要您的不变量成立,它就是安全的。但是,大部分大型代码库强制执行的不变量很少保持不变。
至少,我会在这里插入Assert(dynamic_cast<...>(...))
,并在每个位置parent
被修改,以试图在调试中强制执行不变量。
另一种方法是公开virtual Root* as_root()
,只返回nullptr
中的非Root
。这比(大多数)static_cast
更昂贵,但将演员逻辑放在一个可搜索的中心位置。很少有这种virtual
电话是您的计划的瓶颈。
更有趣的是'如果找不到Root
,你会怎么做?可能返回nullptr
,这意味着在所有调用站点处理它,至少在调试Assert
级别。如果假定呼叫站点不处理它,则返回Root&
,并在调试中调用终止/退出(在Assert
之后)(如果在那里检查,则在发布/通知/之后释放)等)。