C++ 虚析构函数-(一个带有虚函数功能的类,则它需要一个虚析构函数)

c++ 专栏收录该内容
32 篇文章 0 订阅

一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏

下面是基类没有使用虚析构的例子,如果派生类中的析构函数中进行内存释放,就会导致内存泄露:

#include <iostream>
using namespace std;
class ClxBase
{
	public:
		    ClxBase() {cout << "i am ClxBase! create" << endl;};
		    ~ClxBase() {cout << "i am ClxBase! destroy" << endl;};
			virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};

class ClxDerived : public ClxBase
{
	public:
		    ClxDerived() {cout << "i am ClxDerived! create" << endl;};
		    ~ClxDerived() { cout << "i am ClxDerived! destroy" << endl; }; 
			void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};

/*
纯虚函数必须被重写
虚函数可以被重写
这样当基类指针指向子类对象时候,调用函数时候即就是调用子类的函数的
*/
int main()
{
	ClxBase *pTest = new ClxDerived;
	pTest->DoSomething();
	delete pTest;
	return 0;
}



输出:
i am ClxBase! create
i am ClxDerived! create
Do something in class ClxDerived!
i am ClxBase! destroy//为何派生类的析构未调用呢?

注意:基类--子类均有DoSomething(),且是一般的函数则
class ClxDerived : public ClxBase
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();调用基类的函数
delete pTest ;释放派生类对象:先执行派生类的析构再执行基类的析构


但是上面输出结果为什么?

派生类对象的地址可以赋给指向基类对象的指针变量,也就是说,指向基类对象的指针变量也可以指向派生类对象。
总结<--通过指向基类对象的指针,只能访问派生类中的基类成员,而不能访问派生类增加的成员-->
人们有时希望通过使用基类指针能够调用基类和子类对象的成员, 但在应用上却不能完全满足人们的希望。

现知道基类对象的指针变量指向了派生类对象,那如何通过基类指针变量调用派生类对象的函数?
答:只需要让基类为虚函数, 子类重写该函数就行了,这样通过指向基类对象的指针指向派生类变量,再通过基类指针访问派生类函数就行


=======================================================

解决办法:基类中改为虚析构

#include <iostream>
using namespace std;
class ClxBase
{
	public:
		    ClxBase() {cout << "i am ClxBase! create" << endl;};
		    virtual ~ClxBase() {cout << "i am ClxBase! destroy" << endl;};
			virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};

class ClxDerived : public ClxBase
{
	public:
		    ClxDerived() {cout << "i am ClxDerived! create" << endl;};
		    ~ClxDerived() { cout << "i am ClxDerived! destroy" << endl; }; 
			void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};


int main()
{
	ClxBase *pTest = new ClxDerived;
	pTest->DoSomething();
	delete pTest;
	return 0;
}



输出如下:
i am ClxBase! create
i am ClxDerived! create
Do something in class ClxDerived!
i am ClxDerived! destroy

i am ClxBase! destroy



阳光梦总结:如果你有一个带有虚函数功能的类,则它需要一个虚析构函数,原因如下

1. 如果一个类有虚函数功能,它经常作为一个基类使用。


2.如果它是一个基类,它的派生类经常使用new来分配。


3.如果一个派生类对象使用new来分配,并且通过一个指向它的基类的指针来控制,那么它经常通过一个指向它的基类的指针来删除它如果基类没有虚析构函数,结果将是不确定的,实际发生时,派生类的析构函数永远不会被调用)。


  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值