我对使用虚拟析构函数的时间和原因感到困惑。
class Q {
private:
int i;
int *pi;
int *p;
public:
Q(int k);
print();
~Q() {delete pi; delete p;}
};
class DQ : public Q
{
private:
int *pd;
public:
DQ();
~DQ();
};
据我所知,如果主要是我分配了一个
Q *p = new DQ();
并删除p,然后只调用Q的析构函数。
但是每种情况都会发生什么:
答案 0 :(得分:4)
1。)如果~Q()
是虚拟的,~DQ()
是虚拟的,无论你是否写virtual
,所以两个析构函数都将被调用
2。)调用delete p;
是未定义的行为(可能只会调用Q
的析构函数,但可能会崩溃或执行任何数量的操作,因为它未定义)。虚拟传播向下传播,而不是传播。
3。)与#1相同的情况除了你明确地写了virtual
(顺便说一句,这是一个好习惯)。两个析构函数都将被称为
答案 1 :(得分:2)
我对使用虚拟析构函数的时间和原因感到困惑。
您需要在基类中使用虚拟析构函数才能以多态方式删除对象;也就是说,通过指向基类型的指针删除派生类型的对象。
据我所知,如果在main中我分配一个
Q *p = new DQ();
并删除p,那么只调用Q的析构函数。
不,你得到未定义的行为。它可能会调用Q的析构函数,或者它可能会向您的老板发送一封侮辱性的电子邮件 - 第一个更有可能,但原则上任何事情都可能发生。
只有~Q()是虚拟的而~DQ()不是?
那是不可能的。如果一个函数在一个类中是虚函数,那么它在任何派生类中也是虚函数。
只有~DQ()是虚拟的,而~Q()不是?
然后,您不能通过指向DQ
的指针删除Q
类型的对象;如果你尝试,你会得到未定义的行为。但是,如果从DQ
派生另一个类,那么由于其虚拟析构函数,您可以通过指向DQ
(但不 Q
)的指针删除它们。
~Q()是虚拟的,〜DQ()是虚拟的吗?
然后一切都很好,你可以通过基类指针安全地删除对象。
答案 2 :(得分:1)
1.~DQ()和~Q()按~DQ(),~Q()的顺序调用。 2.只调用~Q()。 3.Both~DQ()和~Q()被调用。