虚析构

 派生类有两部分:基类和派生类自己的部分

派生类在构造时:基类的构造函数构造基类部分,派生类自己的构造函数构造派生类部分,析构同样

#include<iostream>
using namespace std;
class Base
{
public:
	Base(int a) :ma(a)
	{
		cout << "Base::Base()" << endl;
	}
	~Base()
	{
		cout << "Base::~Base()" << endl;
	}
	virtual void show()
	{
		cout << "Base::show()" << endl;
	}
protected:
	int ma;
};
class Derive:public Base
{
public:
	Derive(int b) :mb(b), Base(b)
	{
		cout << "Derive::Derive()" << endl;
	}
	~Derive()
	{
		cout << "Derive::~Derive()" << endl;
	}
	void show()
	{
		cout << "Derive::show()" << endl;
	}
private:
	int mb;
};
int main()
{
	Base* pb = new Derive(10);
	pb->show();
	delete pb;
}

运行结果:

 通过测试,发现派生类对象未析构,产生内存泄露。

通过在派生类中加入new的重载

void* operator new(size_t size)
{
		void* ptr = malloc(size);
		cout << "newaddr:" << ptr << endl;
		return ptr;
}

在基类中加入delete的重载

void operator delete(void* ptr)
{
		cout << "deleteaddr:" << ptr << endl;
		free(ptr);
}

测试结果:

分析原因:

Base* pb = new Derive(10);
    pb->show();
    delete pb;

在此为基类指针指向派生类对象,但是基类指针只用到(即只指向)基类部分。在new的时候内核维护了一个数据结构来记录开辟时的首地址和总大小。

可是构造的时候从vfptr开始构造,但是析构是时候从基类部分开始析构了。

释放的地址与开辟时的地址进行匹配,匹配不到,编译器认为释放的是非法地址,所以程序崩溃。

#include<iostream>
using namespace std;
class Base
{
public:
	Base(int a) :ma(a)
	{
		cout << "Base::Base()" << endl;
	}
	virtual ~Base()
	{
		cout << "Base::~Base()" << endl;
	}
	virtual void show()
	{
		cout << "Base::show()" << endl;
	}
protected:
	int ma;
};
class Derive:public Base
{
public:
	Derive(int b) :mb(b), Base(b)
	{
		cout << "Derive::Derive()" << endl;
	}
	~Derive()
	{
		cout << "Derive::~Derive()" << endl;
	}
	void show()
	{
		cout << "Derive::show()" << endl;
	}
private:
	int mb;
};
int main()
{
	Base* pb = new Derive(10);
    pb->show();
	delete pb;
	//实际在此编译器为我们做了pb->~Base() 由于~Base()不是虚函数,
	//所以在此产生的是静多态
	//在销毁是值调用了基类的析构函数,派生类对象未进行析构,内存泄露
	//那如何修改呢???
	//1、强转
	Derive* pd = (Derive*)pb;
	delete pd;
	//2、利用虚函数机制
	//在基类析构函数前加上virtual关键字产生虚析构,则符合动多态的发生条件
	//再delete pb时就会进行操作:pb->~Derive(),
	//且会自动调用基类的析构函数,在此就会call eax,而不是函数入口地址
}

运行结果:

 

猜你喜欢

转载自blog.csdn.net/Aspiration_1314/article/details/86544851