在类似下面代码的情况下,在多态类上使用static_cast后,我可以安全地调用虚函数吗?或者是UB吗?
#include <iostream>
class Base
{
public:
virtual void foo() { std::cout << "Base::foo() \n"; }
};
class Derived : public Base
{
public:
virtual void foo() { std::cout << "Derived::foo() \n"; }
};
int main()
{
Base* derived = new Derived;
Derived* _1 = static_cast<Derived*>(derived);
_1->foo();
}
答案 0 :(得分:5)
是的,你可以。虽然我没有在你的具体例子中看到这样做的重点。只需将其称为
derived->foo();
没有任何演员阵容会产生完全相同的效果。即在这种情况下,某种static_cast
将由虚拟呼叫机制隐式执行。
请注意,static_cast
不会以任何方式抑制通话的“虚拟”性质。
这实际上让我想知道你的问题到底是什么。为什么你甚至会问它?你想做什么?在您的代码示例中,您真正代表了您要做的事情吗?
答案 1 :(得分:2)
如果编译器允许你static_cast
并且在运行时对象的动态类型是预期的,那么是的,你可以。问题是你为什么要这样做......
答案 2 :(得分:1)
是的,但正如其他人所说,你不需要将指针强制转换为派生类型来调用虚函数。
但是,在处理继承的类时使用dynamic_cast
通常更安全。如果类型信息在运行时不正确,则使用dynamic_cast
将生成正确的错误。
Derived* d = dynamic_cast<Derived*>(derived); //safer, but still unnecessary in this situation
答案 3 :(得分:0)
正如所写,这将起作用,主要是因为derived
是Derived*
。所以,所有演员正在做的是告诉编译器你已经知道的东西。然后,即使没有静态演员,您最终也会在输出中结束Derived::foo
。所以,这有点无意义。但是,您可能需要在您完全确定知道变量的实际实例类型并且由于某种原因需要访问某些非虚拟成员的情况下执行此操作。如果您使用设计糟糕的类库,例如......
但是,一般来说,静态向下倾斜是一个坏主意。您最终可能会尝试向下转换不 a Derived*
的变量,在这种情况下,调用虚拟(或非虚拟)函数(或者,事实上,使用该指针几乎所有非平凡的操作都会导致未定义的行为。