前言:
此文章仅作本人学习笔记留存分享。如有出错欢迎指正。
正文:
有时候,实施多态是通过将基类的指针指向派生类的对象来完成的,如果要删除该指针所指的派生类对象时就应该调用该指针所指向的派生类的析构函数,然后派生类的析构函数又调用基类的析构函数,这样整个派生类的对象才能被完全释放。
析构函数也是类的一个成员函数,但使用父类的指针操作它时,他肯定调用的是父类的析构函数。要想得到正确结果,只能把析构函数声明为虚函数。
何时需要虚析构函数?
- 通过基类指针删除派生类对象时;
- 通过基类指针调用对象的析构函数。
代码实验
1.未将析构函数声明为虚函数时
class CRole
{
protected:
char* name;
public:
CRole(char* n) {
name = new char[strlen(n) + 1];
strcpy(name, n);
cout << "调用CRole构造函数." << endl;
}
//为方便直接在类中定义了函数
//未将析构函数声明为虚函数
~CRole() {
delete []name;
cout << "调用CRole析造函数." << endl;
}
virtual void printInfo() { cout << "CRole:" << name << endl; }
};
class CPlane :public CRole
{
public:
CPlane(char* n):CRole(n) {
name = new char[strlen(n) + 1];
strcpy(name, n);
cout << "调用CPlane构造函数." << endl;
}
~CPlane() {
cout << "调用CPlane析造函数." << endl;
}
void printInfo() { cout << "CPlane:" << name << endl; }
};
.cpp的main函数中的内容为
CRole* a = new CRole("A");
a->printInfo();
delete a;
cout << endl;
CRole* aa = new CPlane("AA");
aa->printInfo();
delete aa;
cout << endl;
用new命令建立派生类对象时返回的是派生类指针,根据赋值兼容规则,可以把派生类指针赋给基类指针。
当用delete 基类指针 来删除派生类对象时,只调用基类的析构函数,不能释放派生类对象自身占有的内存空间。
运行结果如下,可以看到CPlane的析构函数未被调用。
2.将析构函数声明为虚函数时
class CRole
{
protected:
char* name;
public:
CRole(char* n) {
name = new char[strlen(n) + 1];
strcpy(name, n);
cout << "调用CRole构造函数." << endl;
}
//为方便直接在类中定义了函数
//将析构函数声明为虚函数
virtual ~CRole() {
delete []name;
cout << "调用CRole析造函数." << endl;
}
virtual void printInfo() { cout << "CRole:" << name << endl; }
};
class CPlane :public CRole
{
public:
CPlane(char* n):CRole(n) {
name = new char[strlen(n) + 1];
strcpy(name, n);
cout << "调用CPlane构造函数." << endl;
}
~CPlane() {
cout << "调用CPlane析造函数." << endl;
}
void printInfo() { cout << "CPlane:" << name << endl; }
};