虚拟函数和static_cast

virtual functions and static_cast

本文关键字:cast static 函数 虚拟      更新时间:2023-10-16

在以下代码中使用polymorphic类上的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();
}

是的,您可以。尽管在您的特定示例中我看不到这样做的意义。只是称其为

derived->foo();

没有任何演员会产生完全相同的效果。IE。在这种情况下,某种static_cast将通过虚拟呼叫机制隐式执行。

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

实际上让我想知道您的问题的真正是什么。你为什么还要问它?你想做什么?在您的代码样本中,您确实代表了您要做的事情?

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

是的,但是正如其他人所说的,您无需施放指向派生类型的指针来调用虚拟函数。

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

Derived* d = dynamic_cast<Derived*>(derived); //safer, but still unnecessary in this situation 

正如书面的,这将起作用,基本上是因为 derived a Derived*。因此,演员们所做的就是告诉编译器您已经知道的内容。再说一次,即使没有静态铸件,您的输出中最终都会出现Derived::foo。因此,这有些毫无意义。不过,您可能需要在绝对确定您知道变量的实际实例类型并且出于某种原因需要访问某些非虚拟成员的情况。如果您使用的是一个设计良好的课堂库,例如...

,但总的来说,静态沮丧是一个坏主意。您可能最终会尝试降低一个不是 a Derived*的变量,在这种情况下,请调用虚拟(或非虚拟)函数(或实际上,实际上是使用该指针用于几乎任何非 - 琐碎的操作)导致不确定的行为。