C++:虚析构和纯虚析构
一、虚析构 - 若子类中存在指向堆区的属性,须利用虚析构技术(将父类析构函数写成虚函数),在delete时,才会调用子类的析构函数。
#include <iostream>
#include <string>
using namespace std;
class Animal
{
public:
Animal()
{
cout<<"Animal默认构造函数调用"<<endl;
}
// 虚析构函数
// 若子类中存在指向堆区的属性,须利用虚析构技术(将父类析构函数写成虚函数),在delete时,才能调用子类的析构函数。
virtual ~Animal()
{
cout<<"Animal析构函数调用"<<endl;
}
virtual void speak()
{
cout<<"动物在说话"<<endl;
}
};
class Cat: public Animal
{
private:
char* name;
public:
Cat(const char* name)
{
cout<<"Cat有参构造函数调用"<<endl;
this->name = new char[strlen(name)+1];
strcpy(this->name, name);
}
~Cat()
{
cout<<"Cat析构函数调用"<<endl;
if(NULL!=this->name)
{
delete[] this->name;
this->name = NULL;
}
}
void speak()
{
cout<<this->name<<" 小猫在说话"<<endl;
}
};
void doSpeak(Animal* animal)
{
animal->speak();
delete animal;
animal = NULL;
}
int main()
{
doSpeak(new Cat("小黑"));
return 0;
}
二、纯虚析构 - 既要有声明,也须有定义;类内声明,类外定义。
#include <iostream>
#include <string>
using namespace std;
// 存在纯虚析构和虚析构函数,该类为抽象类,不能进行实例化操作
class Animal
{
public:
Animal()
{
cout<<"Animal默认构造函数调用"<<endl;
}
// 纯虚析构 - 既要有声明,也须有定义;类内声明,类外定义。子类不会继承父类中的析构函数,因此在子类中无须重写父类的析构函数。
virtual ~Animal() = 0;
virtual void speak()
{
cout<<"动物在说话"<<endl;
}
};
Animal::~Animal()
{
cout<<"Animal纯虚析构函数调用"<<endl;
}
class Cat: public Animal
{
private:
char* name;
public:
Cat(const char* name)
{
cout<<"Cat有参构造函数调用"<<endl;
this->name = new char[strlen(name)+1];
strcpy(this->name, name);
}
~Cat()
{
cout<<"Cat析构函数调用"<<endl;
if(NULL!=this->name)
{
delete[] this->name;
this->name = NULL;
}
}
void speak()
{
cout<<this->name<<" 小猫在说话"<<endl;
}
};
void doSpeak(Animal* animal)
{
animal->speak();
delete animal;
animal = NULL;
}
int main()
{
doSpeak(new Cat("小黑"));
return 0;
}