我接触过这样的代码:
dynamic_cast<A*>(p)->foo();
当 dynamic_cast 返回 0 时,会出现未定义的行为,这当然是很糟糕的。接着我想,它可能会带来一个可怕的意外,即由于当 p 可以强制转换成 A 类型指针时与执行 static_cast 相同,而当不能进行强制转换时就会产生未定义的行为,编译器可以将 dynamic_cast 转换为 static_cast 并保持符合规范的行为。话虽如此,我使用了编译器浏览器尝试了以下代码:
class A {
virtual void bar() = 0;
};
class B final: public A {
public:
void foo();
void bar() override;
};
void h();
void f(A* const p)
{
dynamic_cast<B*>(p)->foo();
}
令我惊讶的是,每个编译器都保留了 dynamic_cast 调用。是否有什么我误解的地方,或者编译器根本没有进行可能的优化?
dynamic_cast
没有返回空指针。 - MSaltersdynamic_cast
不是必需的。你可能认为这是无关紧要或白日梦,但其实不是。这正是编译器一直在执行的那种优化。这也是 UB 的原因所在。 - Lightness Races in Orbit