虚析构函数 就是 向派生类传递的析构结构
虚函数 是从顶部向下传递
虚析构函数是从底部向上传递的
基类是顶层
#include <iostream>
#include <string>
using namespace std;
class A{
public:
A() = default;
A(string s) :s{ s }{}
virtual ~A(){ cout << "析构函数A\n"; } // 虚析构函数向下传递
virtual void print(){ cout << s << endl; } //虚函数向下传递
private:
string s;
};
class B :public A{
public:
B() = default;
B(string s) :s{ s },A(s){}
~B(){ cout << "析构函数B\n"; }
void print(){ cout << s<<endl; }
private:
string s;
};
class C :public A{
public:
C() = default;
C(string s) :s{ s }, A(s){}
~C(){ cout << "析构函数C\n"; }
void print(){ cout << s<<endl; }
private:
string s;
};
class D final :public B, public A,public C{ //final 声明此类不能当做基类或被派生类 就是一个单独的类
public:
D() = default;
D(string a, string b, string c, string s) :s{ s }, B(b), A(a), C(c){} //这里的调用基类顺序是根据继承顺序来调用的 给D的对象在基类成员赋值 用了基类的成员 ,构造是从上往下 默认构造函数也是如此
~D(){ cout << "析构函数D\n"; } // 析构结构是从基层顺序相反从下往上析构 先D C A B A 也是跟继承顺序相反的
void print() override final{
A::print();
B::print();
C::print();
cout << s << endl;
} // override 防止与基类虚函数打错名字会异常,final表示虚函数继承到此不在向下派生
private:
string s;
};
int main(){
A *arr[3],p,*pp=&p; //基类指针数组
arr[0] = new A("基类A"); // 根据new的对象让类私有成员赋值
arr[1] = new B("派生类B");
arr[2] = new C("派生类C");
//arr[4] = new D("A", "B", "C", "D");
for (int i = 0; i < 3; i++){
arr[i]->print(); // 基类数组指针根据元素对象调用基类派生类
}
D *d = new D("A", "B", "C", "D");
pp = d;
pp->print(); //D 对象引用基类成员数据并不会丢失因为有虚函数
for (int i = 0; i < 3; i++){
delete arr[i]; // 因为上面没有用virtual虚析构函数所以调用的都是基类析构函数 用了就是先派生类在基类的析构 从下向上
}
cout << endl;
delete pp;
while (true);
return 0;
}