C++ 虚析构函数和纯虚析构函数


#include 

using namespace std;

/************************************************************************/
/*
虚析构函数和纯虚析构函数
1.当父类指针或引用指向子类对象时,若子类中数据成员有在堆区申请空间,父类析构函数需要
声明为虚析构函数或纯虚析构函数,析构时子类的析构函数会被调用,堆区空间会被释放,否则子类对象会出现内存泄漏问题
2.纯虚析构函数需要进行声明和类外定义,否则编译器或报错
/************************************************************************/
class Animal
{
public:
	 Animal()
	 {
		 cout<<"Animal构造函数"<<endl;
	 }

	 //父类虚成员函数
	 virtual void speak()
	 {
		 cout<<"动物在讲话调用"<<endl;
	 }
/*
	//非虚析构函数,父类指针或引用指向子类对象时,只会调用父类析构函数,导致子类析构函数未调用,堆区内存泄漏
	 ~Animal()
	 {
		 cout<<"Animal析构函数调用"<
	 
/*	 //虚析构函数可以解决子类对象堆区空间未释放问题
	 //父类指针或引用指向子类对象时,先调用父类构造函数,再调用子类构造函数;析构时,先调用子类析构函数,再调用父类析构函数
	 virtual ~Animal()
	 {
		 cout<<"Animal虚析构函数调用"<

	 //纯虚析构函数也可以达到虚析构同样效果,不但需要声明,还需要有定义
	 //因为含有纯虚成员函数的类为抽象类,无法实例化,但析构时先调用子类析构函数,再调用父类析构函数,所有需要析构函数的定义(函数体),即使是纯虚析构函数
	 virtual ~Animal()=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<<"猫在讲话"<<endl;
	}
	
	~Cat()
	{
		cout<<"Cat析构函数调用"<<endl;
		if (m_name != NULL)
		{
			delete m_name;
			m_name = NULL;
		}
	}
	string *m_name;
};


void dospeak(Animal *pmal)
{
	pmal->speak();

	
	delete pmal;
}


void test1()
{
	
	dospeak(new Cat("Tom"));

}

int main()
{
	test1();

	return 0;	
}

你可能感兴趣的:(C++)