向下动态类型转换应使用 dynamic_cast
12.16 ID_nonDynamicDownCast
向下动态类型转换应使用 dynamic_cast 以保证安全性。
示例:
class A { .... };
class B: public A { .... }; // A and B are polymorphic classes
void foo(A* a)
{
B* b0 = (B*)a; // Non-compliant
B* b1 = static_cast<B*>(a); // Non-compliant
B* b2 = reinterpret_cast<B*>(a); // Non-compliant
B* b3 = dynamic_cast<B*>(a); // Compliant
....
}
如果 a 实际指向的不是 B 类对象,使用 dynamic_cast 会得到一个空值便于进一步处理,其他方式的转换会得到无法判断对错的结果。
注意,虚基类指针只能通过 dynamic_cast 转换为派生类指针,否则会导致标准未定义的行为:
class A { .... };
class B: virtual A { .... };
class C: virtual A { .... };
class D: B, C { .... };
void foo(A* a) {
D* d0 = (D*)a; // Undefined behavior
D* d1 = dynamic_cast<D*>(a); // Right
....
}
应尽量减少向下类型转换,参见 ID_downCast。
相关
依据
ISO/IEC 14882:2003 5.2.7
ISO/IEC 14882:2003 5.2.9(5 8)-undefined
ISO/IEC 14882:2011 5.2.7
ISO/IEC 14882:2011 5.2.9(11 12)-undefined
参考
C++ Core Guidelines C.146
MISRA C++ 2008 5-2-2