2

在以下代码或UB的情况下,在多态类上使用static_cast后,我可以安全地调用虚函数吗?

#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();
}
4

4 回答 4

6

是的你可以。尽管在您的具体示例中我没有看到这样做的意义。只是把它称为

derived->foo();

没有任何演员表会产生完全相同的效果。static_cast即,在这种情况下,虚拟调用机制会隐式执行某种操作。

请注意,您static_cast不会以任何方式抑制呼叫的“虚拟”性质。

这实际上让我想知道你的问题到底是关于什么的。你为什么还要问这个?你想做什么?在您的代码示例中真正代表您正在尝试做什么?

于 2012-10-22T17:36:31.467 回答
2

如果编译器允许您static_cast并且在运行时对象的动态类型符合预期,那么是的,您可以。问题是你为什么要这样做...

于 2012-10-22T17:39:11.370 回答
1

是的,但正如其他人所说,您不需要将指针强制转换为派生类型来调用虚函数。

dynamic_cast但是,在处理继承的类时使用它通常更安全。dynamic_cast如果在运行时类型信息不正确,使用将产生正确的错误。

Derived* d = dynamic_cast<Derived*>(derived); //safer, but still unnecessary in this situation 
于 2012-10-22T17:43:59.553 回答
0

正如所写,这将起作用,主要是因为derived 一个Derived*. 所以,演员所做的只是告诉编译器你已经知道了什么。再说一次,即使没有静态演员表,你最终也会得到Derived::foo你的输出。所以,这有点毫无意义。尽管如此,您可能需要在您绝对确定您知道变量的实际实例类型并且出于某种原因需要访问一些非虚拟成员的情况下执行此操作。例如,如果您使用的是设计糟糕的类库...

但是,一般来说,静态向下转换是一个坏主意。您最终可能会尝试向下转换不是a的变量Derived*,在这种情况下,调用虚拟(或非虚拟)函数(或者实际上,将该指针用于几乎所有非平凡操作)会导致未定义行为。

于 2012-10-22T17:42:33.583 回答