通过阅读下面的代码以及将其置于编译器上编译运行:
#include<iostream>
using namespace std;
class Father {
public:
	Father(const char* addr="中国") {
		cout << "执行Father类构造函数" << endl;
		int len = strlen(addr) + 1;
		this->addr = new char[len];
		strcpy_s(this->addr, len, addr);
	}
	~Father() {
		cout << "执行Father类析构函数" << endl;
		delete addr;
		addr = NULL;
	}
private:
	char* addr;
};
class Son :public Father {
public:
	Son(const char* game="联盟",const char*addr="中国"):Father(addr) {
		cout << "执行Son类构造函数" << endl;
		int len = strlen(game) + 1;
		this->game = new char[len];
		strcpy_s(this->game, len, game);
	}
	~Son() {
		cout << "执行Son类析构函数" << endl;
		delete game;
		game = NULL;
	}
private:
	char* game;
};
int main(void) {
	cout << "----case 1----" << endl;
	Father* father = new Father();
	delete father;
	cout << endl;
	cout << "----case 2----" << endl;
	Son* son = new Son();
	delete son;
	cout << endl;
	
	system("pause");
	return 0;
} 
运行结果:

结果完全符合我们的预期,但是就此可以说明我们的代码就完全正确或者说不存在致命错误???
我们不妨在源代码中加入这样一种情况:用父类指针指向子类对象
Father* father = new Son();
delete father; 
完整代码:
#include<iostream>
using namespace std;
class Father {
public:
	Father(const char* addr="中国") {
		cout << "执行Father类构造函数" << endl;
		int len = strlen(addr) + 1;
		this->addr = new char[len];
		strcpy_s(this->addr, len, addr);
	}
	~Father() {
		cout << "执行Father类析构函数" << endl;
		delete addr;
		addr = NULL;
	}
private:
	char* addr;
};
class Son :public Father {
public:
	Son(const char* game="联盟",const char*addr="中国"):Father(addr) {
		cout << "执行Son类构造函数" << endl;
		int len = strlen(game) + 1;
		this->game = new char[len];
		strcpy_s(this->game, len, game);
	}
	~Son() {
		cout << "执行Son类析构函数" << endl;
		delete game;
		game = NULL;
	}
private:
	char* game;
};
int main(void) {
	Father* father = new Son();
	delete father;
	cout << endl;
	system("pause");
	return 0;
} 
运行结果:

我们会惊奇的发现:子类的析构函数没有被执行 ,这样将会导致内存泄漏,引发严重后果;
重要:
为了防止内存泄漏,最好是在基类(父类)析构函数上添加virtual关键字,使基类析构函数为虚函数
目的在于:
当使用delete释放基类指针时,会实现动态的析构;
如果基类指针指向的是基类对象,那么只调用基类的析构函数;
如果基类指针指向的是子类对象,那么先调用子类的虚构函数,再调用父类的析构函数.
正确代码:
#include<iostream>
using namespace std;
class Father {
public:
	Father(const char* addr="中国") {
		cout << "执行Father类构造函数" << endl;
		int len = strlen(addr) + 1;
		this->addr = new char[len];
		strcpy_s(this->addr, len, addr);
	}
	virtual ~Father() {
		cout << "执行Father类析构函数" << endl;
		delete addr;
		addr = NULL;
	}
private:
	char* addr;
};
class Son :public Father {
public:
	Son(const char* game="联盟",const char*addr="中国"):Father(addr) {
		cout << "执行Son类构造函数" << endl;
		int len = strlen(game) + 1;
		this->game = new char[len];
		strcpy_s(this->game, len, game);
	}
	~Son() {
		cout << "执行Son类析构函数" << endl;
		delete game;
		game = NULL;
	}
private:
	char* game;
};
int main(void) {
	cout << "----case 1----" << endl;
	Father* father = new Father();
	delete father;
	cout << endl;
	cout << "----case 2----" << endl;
	Son* son = new Son();
	delete son;
	cout << endl;
	cout << "----case 3----" << endl;
	father = new Son();
	delete father;
	cout << endl;
	system("pause");
	return 0;
} 
运行结果:



















![[TIFS 2022] FLCert:可证明安全的联邦学习免受中毒攻击](https://img-blog.csdnimg.cn/ef73634b20104948a4ff91975251f2ad.png)
