不是多态类型,或者为什么我们在这里需要虚拟析构函数?
Not a polymorphic type or why do we need virtual destructors here?
目前我正在学习动态转换,因此我正在测试各种代码片段。
我测试了下面的代码,有和没有 (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类型。 这要求类至少有一个虚函数,如上所述。
相关文章:
- 努力将整数转换为链表。不知道我在这里做错了什么
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- File.cpp.o:OpenPose 标志 CMakeFiles/.. 的多重定义/main.cpp.o:首先在这里定
- 为什么thread_local变量在这里从未初始化?
- 为什么我必须在这里使用dynamic_cast
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 为什么 C++20 中的 [[可能]] 属性在这里引发警告?
- 我在这里正确传递参数了吗?
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 移动语义在这里如何工作?
- 如何在这里循环运行?
- 为什么枚举变量在这里是右值?
- 我的C++合并排序代码不起作用。我在这里错过了什么?
- 试图美化这个Arduino代码[初学者在这里]
- 有没有办法在没有虚拟的情况下使用基类指针调用派生类函数
- 我是否应该在包含虚拟方法的类上使用'memcpy'?如果没有,如何替换它?
- 复制交换习惯用法-我们可以在这里使用动态强制转换操作吗
- 不是多态类型,或者为什么我们在这里需要虚拟析构函数?