不是多态类型,或者为什么我们在这里需要虚拟析构函数?

Not a polymorphic type or why do we need virtual destructors here?

本文关键字:在这里 虚拟 析构函数 我们 为什么 多态 类型 或者      更新时间:2023-10-16

目前我正在学习动态转换,因此我正在测试各种代码片段。

我测试了下面的代码,有和没有 (2) 中标记的虚拟析构函数,发现 (3) 行只有在有 (2) 行的情况下才是正确的。没有它,代码将无法编译。但是为什么?有趣的是,似乎根本不需要第 (1) 行。

struct A {
virtual ~A() = default; \ (1)
};
struct B {
virtual ~B() = default; \ (2)
};
struct D : A, B {};
B* pb = new D();
A* pa = dynamic_cast<A*>(pb); \ (3)

一般

dynamic_cast需要确定运行时的行为。 根据强制转换对象的实际类型,它将返回目标类型的nullptr或有效指针。

若要在运行时执行此操作,C++实现需要在运行时访问有关类型的一些附加信息。 管理此信息需要执行一些额外的操作。 开销很小,但它存在。

并非总是需要动态转换。 C++语言设计器已决定在不需要时不产生不必要的开销。 因此,除非你说需要多态性,否则编译器将尝试在编译时尽可能多地解决所有类型问题。

说需要多态性和动态类型的方法是在类中至少有一个虚拟成员函数

您的具体情况

如果您在程序中非常了解源对象的类型与目标对象类型兼容,则可以按照此处的说明使用static_cast

但这在您的情况下不起作用,因为pb*B(静态类型),因为通常不能将*B强制转换为*A,因为这两种类型完全不相关。

但是,鉴于*D(动态类型)的多重继承,可以将其强制转换为*A。这就是为什么这里需要dynamic_cast:跟踪pb指向的物体的原始D类型。 这要求类至少有一个虚函数,如上所述。