什么是虚析构函数?为什么需要虚析构函数?
时间: 2023-08-13 07:09:13 浏览: 101
在C++中,如果一个类中有虚函数,我们通常都会将它的析构函数设为虚析构函数。虚析构函数是指在基类中将析构函数声明为虚函数,这样在删除指向派生类对象的基类指针时,会调用派生类的析构函数。
需要虚析构函数的主要原因是防止内存泄漏。当我们在使用多态时,通常会使用基类指针来指向派生类对象,这时如果析构函数不是虚函数,删除指向派生类对象的基类指针时,只会调用基类的析构函数,而不会调用派生类的析构函数。这就会导致派生类中申请的动态内存无法被释放,从而造成内存泄漏。
使用虚析构函数可以保证在删除指向派生类对象的基类指针时,会先调用派生类的析构函数,从而保证所有动态内存都能正确释放。
举个例子,假设我们有一个基类 Animal 和一个派生类 Cat。Animal 类中有一个指针类型的成员变量,指向一个动态分配的字符串。Cat 类继承自 Animal 类,并且重载了析构函数。如果 Animal 类的析构函数不是虚函数,那么在删除指向 Cat 对象的 Animal 指针时,只会调用 Animal 类的析构函数,从而导致 Cat 类中申请的动态内存无法被释放,造成内存泄漏。
```c++
class Animal {
public:
Animal() {
name = new char[20];
strcpy(name, "Animal");
}
~Animal() {
delete[] name;
cout << "Animal destructor" << endl;
}
protected:
char* name;
};
class Cat : public Animal {
public:
Cat() {
name = new char[20];
strcpy(name, "Cat");
}
~Cat() {
delete[] name;
cout << "Cat destructor" << endl;
}
};
int main() {
Animal* p = new Cat();
delete p; // Animal destructor,没有调用 Cat 的析构函数,造成内存泄漏
return 0;
}
```
如果将 Animal 类的析构函数声明为虚析构函数,那么在删除指向 Cat 对象的 Animal 指针时,就会先调用 Cat 类的析构函数,从而正确释放动态内存。
```c++
class Animal {
public:
Animal() {
name = new char[20];
strcpy(name, "Animal");
}
virtual ~Animal() { // 声明为虚析构函数
delete[] name;
cout << "Animal destructor" << endl;
}
protected:
char* name;
};
class Cat : public Animal {
public:
Cat() {
name = new char[20];
strcpy(name, "Cat");
}
~Cat() {
delete[] name;
cout << "Cat destructor" << endl;
}
};
int main() {
Animal* p = new Cat();
delete p; // Cat destructor,然后 Animal destructor
return 0;
}
```
阅读全文