繁体   English   中英

虚拟类的析构函数到底做什么?

[英]What do destructors for virtual classes do exactly?

说我们上课了。

class A 
{
public:

   void doSomething() = 0;
   A();
   virtual ~A();

private:

   vector<SomeStuff> cont;
   bool yesNo;

}

class B: public A
{

public:

   B();
   ~B();

private:

   bool Byesno;
}

因此,首先调用A的构造函数,然后再调用B的构造函数,然后销毁B时,首先调用B的析构函数,然后再调用A的析构函数。 因此,基本上,A的析构函数将删除B的继承变量,而B的析构函数将删除其特定于类的变量。 我对吗?

我不明白的是,即使我们无法实例化类型为A的对象,如何调用A的析构函数? 它在内部如何运作?

B是A等。 A的析构函数将被调用以确保B的A部分被清除。 您的类不使用virtual关键字,所以我不确定您为什么想知道虚拟析构函数,但是由于您想知道这样做可能会有所帮助:

class A
{
   public:
       virtual ~A() { cout << "A::~A()" << endl; }
};

class B : public A
{
   public:
       ~B() { cout << "B::~B()" << endl; }
};

int main()
{
    A* obj = new B();
    delete obj;
    return 0;
}

您所期望的输出将是

B::~B()
A::~A()

但是,如果您未将A的析构函数声明为虚拟,则输出将只是

A::~A()

因此,总之,如果您的代码涉及多态性,并且您想要调用指向对象的析构函数而不是指针类型本身的析构函数,则必须声明基类析构函数virtual。

每个析构函数都经历三个阶段:

  1. 用户密码
  2. 将销毁类成员委托给各自的析构函数
  3. 将基类的销毁委托给相应的析构函数

基本类型的析构函数通常是微不足道的,即不执行任何操作。 从技术上讲,您可能会想到

B::~B() { Byesno = false; }

B::~B()
{
    Byesno = false;  // explicit
    Byesno.~bool();  // implicit, member
    A::~A();         // implicit, base class
}


A::~A()
{
    yesNo.~bool();   // implicit, member
    cont.~vector();  // implicit, member
}

~bool()是空的,将被内联,所以只能叫你能看到的是一个~vector()

所有这一切都被称为d'tor。 如果A的d'tor是非虚拟的,则仅当已知被破坏的对象是B对象时,才会调用B的d'tor:

A a;
B b;
A *ap = new B;
delete ap;

这将使用~A()a对象(正确的), ~B()b对象(也是正确的),并~A()为指向的对象ap (不正确的,但我们不知道更好)。 如果〜A ~A()是虚拟的,则将在v'表中查找d'tor调用本身,该表中包含指向〜B ~B()的指针。

比这稍微复杂一点 ,但不多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM