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

问题描述 投票:0回答:1

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

我测试了下面的代码,有或没有(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)
c++ polymorphism virtual multiple-inheritance dynamic-cast
1个回答
0
投票

In general

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

为了在运行时发生这种情况,C ++实现需要访问一些额外的information about the type at run-time。管理此信息需要执行一些额外的操作。开销很小但存在。

不总是需要动态铸造。如果不需要,C ++语言设计者决定不创建不必要的开销。因此,除非您说需要多态,否则编译器将尝试在编译时尽可能多地解决所有类型问题。

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

Your specific case

如果您在程序中非常清楚源对象的类型与目标对象类型兼容,则可以使用static_cast,如here所述。

但这不适用于你的情况,因为pb是一个*B(静态类型),因为一般来说*B不能被铸造到*A,因为这两种类型完全不相关。

但是考虑到它的多重继承,*D(动态类型)可以被铸造到*A。这就是为什么需要dynamic_cast的原因:跟踪pb指向的对象的原始D类型。并且这要求类至少具有如上所述的虚函数。

© www.soinside.com 2019 - 2024. All rights reserved.