0
点赞
收藏
分享

微信扫一扫

C++ 41.类与对象—多态的虚析构和纯虚析构

金刚豆 2022-03-19 阅读 73

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:1.可以解决父类指针释放子类对象  2.都需要有具体的函数实现  
虚析构和纯虚析构区别:如果是纯虚析构,该类属于抽象类,无法实例化对象
虚析构语法:virtual ~类名(){}
纯虚析构语法:virtual ~类名()=0;
补充:实例化是指在面向对象的编程中,把用类创建对象的过程称为实例化。 是将一个抽象的概念类,具体到该类实物的过程。 实例化过程中一般由类名 对象名 = new 类名(参数1,参数2...参数n)构成。 如 Date date=new Date ();就是用日期类创建了一个日期的对象,就叫对象的实例化

#include<iostream>
using namespace std;
#include<string>

class Animal
{
public:
	Animal()
	{
		cout << "Animal 构造函数调用 " << endl;
	}

	//利用虚析构可以解决,父类指针释放子类对象时不干净的问题
	//virtual~Animal()          
	//{
	//	cout << "Animal 析构函数调用 " << endl;
	//}

	//纯虚析构,需要声明也需要实现
	//有了纯虚析构后,这个类也属于抽象类,无法实例化对象
	virtual~Animal()= 0;         

	//纯虚函数 
	virtual void speak() = 0;
};

Animal::~Animal() //纯虚析构
{
	cout << "Animal 纯虚析构函数调用 " << endl;
}

class Cat :public Animal
{
public:
	Cat(string name)
	{
		cout << "Cat 构造函数调用 " << endl;
		m_Name = new string(name);//堆区需要释放干净
	}
	virtual void speak()
	{
		cout << *m_Name << "  cat speak" << endl;
	}
	string * m_Name;//指针
	~Cat()
	{
		if (m_Name != NULL)
		{
			cout << "Cat 析构函数调用 " << endl;
			delete m_Name;
			m_Name = NULL;
		}
	}
};

void test01()
{
	Animal * animal = new Cat("Tom");//父类指向子类对象
	animal->speak();
	//父类指针在析构时,不会调用子类中析构函数,导致子类如果有堆区属性,出现内存泄露
	//解决办法:Animal改为虚析构
	delete animal;
}

int main()
{
	test01();

	system("pause");
	return 0;
}
举报

相关推荐

C++ 虚表与虚析构

0 条评论