具有非虚拟destirutor的双重继承(Y形)
Double inheritance with non-virtual destirutor (Y-shaped)
我有Y形的类层次结构:类C继承自A和B,类D继承自C。A和B有虚拟析构函数,而C的析构函数不是虚拟的。我知道如果没有双重继承(说没有B)~C()将是虚拟的。我的问题是双重继承会影响它吗?
class A { virtual ~A(); ...};
class B { virtual ~B(); ...};
class C : public A, public B { ~C(); ...};
class D : public C { virtual ~D(); ... };
我必须通过指向C.的指针删除类D的实例
C* c = new D;
delete c;
我怀疑有些情况下~B()没有被执行——这可能吗?它是否取决于优化级别?在调用"delete c"的.cc文件中是否应该存在to D的定义?
除了~B()之外的所有析构函数都是nops,类C是空类:没有数据成员,没有函数,只有一个平凡的构造函数和一个空析构函数。我在所有情况下都写了几个测试程序~B()被执行,但我确信我没有尝试所有可能的组合。
C
析构函数是隐式虚拟的,因为它的基析构函数中至少有一个是虚拟的。
因此,因为C
析构函数是虚拟的,并且您通过指向C
的指针进行删除,所以会调用D
析构函数。
如果A
或B
析构函数都不是虚拟的,那么删除D
对象将是未定义的行为,但这里的情况并非如此。
如果类C
派生自类,那么它知道如何销毁其基类。因此,B
析构函数将始终被调用(假设您删除了最终对象,或者从析构函数是显式或隐式虚拟的级别中删除
在实践中,即使在未定义的情况下(只有D
析构函数是虚拟的,对象是通过C
指针删除的),也可能会调用B
析构函数,但D
部分不会被正确销毁但由于它是未定义的,您不能依赖它。
C的析构函数不是虚拟的。
是的。它有一个带虚拟析构函数的基,所以C的析构函数是隐式虚拟的。析构函数是否显式声明为虚拟是无关紧要的。D.的析构函数也是如此
我必须通过指向C的指针删除类D的实例。
我怀疑有些情况下~B()没有被执行——这可能吗?
只要C的析构函数是虚拟的,就没有问题。如果C的析构函数不是虚拟的,那么通过指向C的指针删除一个dervied对象将具有未定义的行为。
据我所知,析构函数链接与虚拟析构函数无关。只要调用了某个类的析构函数,它就会自动为您调用基类解构函数。
当您通过基类的指针删除派生类实例时,Desconstructor的虚拟性就会显现出来。
在上面的例子中,假设~C
不是虚拟的(即,您没有为任何析构函数声明虚拟的),并且如果您通过C*
删除D
实例,则可能会错过D的析构函数,编译器将为您调用~C
。如上所述,调用~C
将导致所有基类去分配器(~A
&~B
)被自动调用。
然而,假设您已经在基类(A
等)中将析构函数声明为虚拟的,那么虚拟性将传播到所有派生类的析构函数。这意味着,即使您没有将~C
声明为虚拟的,它实际上也是虚拟的。
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 大小虚拟继承中的派生类
- 删除C++继承中虚拟类成员的代码重复
- 重写虚拟函数和继承
- C++ 多级虚拟继承编译问题
- 如何正确获得虚拟继承?
- 编译时继承类中的隐式虚拟与显式虚拟
- 钻石继承虚拟成员铸造与指针
- CPP 继承虚拟方法解析顺序
- 关于C 接口(纯虚拟类)/多重继承/虚拟继承的设计Qustion
- 继承虚拟类C 的派生类
- 多个继承/虚拟函数
- 不能从具有虚拟继承(C++虚拟继承)的类派生
- C++多重继承+虚拟函数(-歧义)=怪异行为(也是函数指针)
- 为什么我不能继承虚拟基的构造函数?
- C++继承虚拟函数崩溃
- c++多重继承/虚拟继承
- 派生类的成员函数是否从基类继承虚拟性?
- 继承虚拟函数的类的boost::optional失败的原因
- c++继承虚拟函数