C++的动态析构

 多态是C++的一个重要特性,但是再使用多态的时候又有 非常多的陷阱,例如这个析构函数,请看下面的代码

#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

class Father
{
public:
	Father(const char* _name = "无名")
	{
		cout << __FUNCTION__ << endl;
		int lenth = strlen(_name) + 1;
		this->name = new char[lenth];
		strcpy_s(this->name, lenth, _name);
	}
	// 动态析构
	virtual ~Father()
	{
		cout << __FUNCTION__ << endl;
		if (this->name) {
			delete this->name;
		}
		this->name = nullptr;
	}
private:
	char* name;
};

class Son final : public Father
{
public:
	Son(const char* _game = "LOL", const char* _name = "张云翔"):
	Father(_name)
	{
		cout << __FUNCTION__ << endl;
		int lenth = strlen(_game) + 1;
		this->game = new char[lenth];
		strcpy_s(this->game, lenth, _game);
	}
	~Son()
	{
		cout << __FUNCTION__ << endl;
		if (this->game) {
			delete game;
		}
		game = NULL;
	}
private:
	char* game;
};



int
main(int agrc, char** argv)
{
	string line(50, '-');
	Father *fa = new Father;
	delete fa;
	cout << line << endl;

	Son *so = new Son;
	delete so;
	cout << line << endl;

	// 多态得形式
	fa = new Son;
	delete fa;

	system("pause");
	return 0;
}

 这个代码是没有问题的,但是如果把父类中析构函数前的virtual 去掉,大家可能看着是没有错误,但是如果去掉的话就会是这个结果,大家会发现怎么成双成对的析构 和构造函数  第三个部分怎么少一个(意味着又内存泄漏,如果再服务器哪种一直运行的案例上是特别可怕的)

 

在父类的析构函数前加上virtual 后  结果:

总结:

把Father类的析构函数定义为virtual函数时,

 如果对 Father类的指针使用delete操作时,

 就会对该指针使用“动态析构”:

 如果这个指针,指向的是子类对象,

 那么会先调用该子类的析构函数,再调用自己类的析构函数

【注意】

为了防止内存泄露,最好是在基类析构函数上添加virtual关键字,使基类析构函数为虚函数

目的在于,当使用delete释放基类指针时,会实现动态的析构:

如果基类指针指向的是基类对象,那么只调用基类的析构函数

如果基类指针指向的是子类对象,那么先调用子类的析构函数,再调用父类的析构函数

猜你喜欢

转载自blog.csdn.net/qq_44065088/article/details/104376377