从具有非虚拟父级的虚拟类继承的正确方法继续
Correct way to inherit from a virtual class with non-virtual parent continued
我的问题是基于这个问题:从具有非虚拟父级的虚拟类继承的正确方法。
我的理解正确吗?在问题中描述的情况下,新分配对象的"三"answers"二"部分正在泄漏,因为它们没有被破坏?
来源:
#include <iostream>
struct One
{
~One() {
std::cout << "~One()n";
}
};
struct Two : One
{
virtual ~Two() {
std::cout << "~Two()n";
}
virtual void test() = 0;
};
struct Three : Two
{
virtual ~Three() {
std::cout << "~Three()n";
}
virtual void test() {
std::cout << "Three::test()n";
}
};
int main()
{
Two* two = new Three;
two->test();
One* one = two;
delete one;
}
是的,没错。内存泄漏的定义是,您无法删除您创建的东西(因此您负责管理其生命周期)。
正如该问题的答案所示,delete one
调用未定义的行为(在大多数情况下,这可能会转化为常规的旧内存泄漏,但情况可能会像鼻恶魔一样糟糕),因为指定对象的运行时类型与其静态(声明的)类型不匹配,并且静态类型没有虚拟析构函数。
C++标准的适用部分如下:
§5.3.5/3:在第一种备选方案(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数动态类型的基类,静态类型应具有虚拟析构函数或行为未定义。
解决方案是要么声明所有析构函数virtual
,要么不通过指向One
的指针删除对象。
相关文章:
- 大小虚拟继承中的派生类
- C++ 多级虚拟继承编译问题
- 如何正确获得虚拟继承?
- 避免C++虚拟继承
- 虚拟继承基构造函数消除
- 虚拟继承中是否存在多重继承?
- 了解虚拟继承类 vtables 和 vptr 创建
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 我是否需要在虚拟继承类的构造函数中初始化基类以解决菱形继承问题?
- C++ 不明确访问 - 虚拟继承
- 虚拟继承中来自基数的虚拟调用
- 虚拟继承:调用没有匹配函数
- 虚拟继承的内部机制
- 联合虚拟继承
- C++虚拟继承类的大小
- C++虚拟继承、虚拟析构函数和 dynamic_cast<void*>
- 虚拟继承构造函数的组装
- 虚拟继承情况下类的意外大小
- 虚拟继承情况下的 vtable
- C++解决没有虚拟继承的钻石继承问题