调用基类的析构函数而不破坏基类!

Nav*_*Nav 1 c++ inheritance destructor ctor-initializer

#include<iostream>
using namespace std;

class A
{
public:
        int i;
        A() {cout<<"A()"<<endl;}
        ~A() {cout<<"~A()"<<endl;}
};
class B:public A
{
public:
        int j;
        B(): j(10)
        {
                this->i=20;
                this->~A();
        }
};

int main()
{
        B abc;
        cout<<"i="<<abc.i<<" j="<<abc.j<<endl;
}//main
Run Code Online (Sandbox Code Playgroud)

两个问题:

  1. 为什么A的析构函数被调用为普通函数而不是破坏对象?(或者只是在子类的析构函数调用基类的析构函数时才会销毁基类的某种规则?)我正在尝试这个示例代码来找出析构函数是如何工作的.因此,如果简单地调用析构函数不会破坏对象,那么显然有一些其他类型的调用会调用析构函数,然后才会破坏对象.那种电话有什么特别之处,有什么电话呢?
  2. 有没有办法在B的构造函数中为A创建一个初始化列表?像这样的东西:

    class B:public A
    { 
        B(): j(10), A():i(20) {}
    };
    
    Run Code Online (Sandbox Code Playgroud)

Kir*_*rov 5

  1. 基类的析构函数应该是虚拟的.在这里,因为它是在堆栈上创建的,它不是问题,但无论如何..
  2. 不,但你可以class A()在B的构造函数的初始化列表中调用构造函数,如下所示:
    B(): A( .. ), ...

A* a = new B();
//..
delete a;
Run Code Online (Sandbox Code Playgroud)

不会调用B的析构函数,除非class A析构函数是虚拟的.这就是为什么不应该派生STL容器 - 他们的析构函数不是虚拟的.

  • 不,基类的析构函数不需要是虚拟的.但很难说原始代码和问题是什么.提供的代码只有未定义的行为. (2认同)

Nav*_*een 5

  1. 析构函数就像你可以调用的任何其他普通函数一样(但除非你使用新的贴图,否则你不应该这样做).当你调用delete一个对象时,会发生两件事:调用析构函数进行清理,然后operator delete调用析构函数来释放为该对象分配的内存.这里第二步没有发生.

  2. 不,你不能这样称呼它.你可以做的是这样的事情:

    A类{public:A(int n):i(n){}};

    B级:公共A {public:B():A(20),j(10){}};