static_cast向下转型可运行dynamic_cast段错误 无额外成员转型安全性咨询
问题结论
即使派生类没有新增任何数据成员,使用static_cast执行向下类型转换(将基类指针/引用转为派生类指针/引用)仍然不安全,属于C++标准明确定义的未定义行为。
示例运行正常的原因
你给出的代码能得到预期输出只是特定编译器、特定场景下的巧合,原因有两个:
- 你定义的
Derived类没有新增非静态数据成员,内存布局和Base类完全一致,调用get2成员函数时访问的_a变量,刚好对应Base实例已经初始化的内存位置,因此能读到正确的值。 get2是非虚成员函数,编译器调用时不会检查虚表,只会把ptr2作为Derived类型的this指针传入函数,执行2*_a的逻辑时刚好能命中有效内存,没有触发崩溃。
为什么这类转换本质不安全
C++标准对static_cast向下转换的安全前提有明确规定:被转换的指针/引用指向的对象,本身必须是目标派生类的实例。你的示例中ptr指向的是纯粹的Base类对象,根本不是Derived实例,不管派生类有没有新增成员,这种转换本身就不符合安全要求,行为完全不受标准约束:
- 换成
dynamic_cast时会触发运行时类型检查,发现指向的对象不是Derived实例,指针转换会返回nullptr,后续解引用空指针调用成员函数自然会触发段错误,这正是dynamic_cast的运行时安全校验作用。 - 即使派生类没有新增数据成员,只要后续修改中给
Derived新增虚函数、新增带构造/析构逻辑的成员、或者编译器开启特殊布局优化,都可能直接触发崩溃、读到垃圾值等不可预期的结果。
内容的提问来源于stack exchange,提问作者Reimundo Heluani
相关产品推荐
相关产品推荐

