析构函数是否需要定义成虚函数?

我们用派生类声明出对象的时候,即使不把析构函数定义成虚函数,析构派生类对象的时候,也会自动调用基类的析构函数。这样看来我们似乎不需要将析构函数定义成虚函数,也不存在什么问题。

class Person{
public:
	~Person()
	{
		cout << "~Person" << endl;
	}
};
class Student :public Person
{
public:
	~Student()
	{
		cout << "~Student" << endl;
	}
};
int main(){
	Person p;//  ~Person
	Student s;// ~Student   ~Person
	
	Person rp = s;//~Person
	return 0;
}

我们接下来在看一个场景:我们用基类的指针去接收用new申请的基类对象的空间,同样派生类也是如此,当我们不需要在使用这个指针的时候,delete掉,防止内存泄漏。delete的时候我们希望这个空间上的对象调用自己的析构函数,完成空间的释放。

class Person{
public:
	 ~Person()
	{
		cout << "~Person" << endl;
	}
};
class Student :public Person
{
public:
	 ~Student()
	{
		cout << "~Student" << endl;
	}
};
int main(){
	
	
	Person* p = new Person;
	delete p;

	Student* s = new Student;
	delete s;
	return 0;
}

似乎这种场景下,析构函数不定义为虚函数,最后的结果也符合我们的期望,也没有内存泄漏问题。 

然而在这个场景下:用基类指针去接收申请的包含派生类对象的空间,当这个指针完成任务之后,我们需要delete掉,防止内存泄漏,我们期望空间中的对象调用自己的析构函数,完成空间的释放,然后事实是?让我们看一下代码。

class Person{
public:
	 ~Person()
	{
		cout << "~Person" << endl;
	}
};
class Student :public Person
{
public:
	 ~Student()
	{
		cout << "~Student" << endl;
	}
};
int main(){
	
	
	Person* p = new Student;
	delete p;

	
	return 0;
}

我们发现在这种场景下,达不到我们的预期。程序只析构了基类,并没有析构派生类,造成了内存泄漏。

此时我们便需要将析构函数定义为虚函数,以达到我们的预期,完成空间的释放,并且不会造成内存泄漏问题。

class Person{
public:
	 virtual ~Person()
	{
		cout << "~Person" << endl;
	}
};
class Student :public Person
{
public:
	 virtual ~Student()
	{
		cout << "~Student" << endl;
	}
};
int main(){
	
	
	Person* p = new Student;
	delete p;
	return 0;
}

总之:在公有继承中,基类对派生类及其对象的操作,只能影响到那些从基类继承下来的成员。如果想要用基类对非继承成员函数进行操作,则要把基类的这个函数定义为虚函数。 
  析构函数自然也应该如此:如果它想析构子类中的重新定义或新的成员及对象,当然也应该把函数定义为虚函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值