面试题答案
一键面试- 未声明虚析构函数的问题:
- 当析构函数未声明为虚函数时,如果通过基类指针删除派生类对象,只会调用基类的析构函数,而不会调用派生类的析构函数。这会导致派生类中动态分配的资源无法释放,从而产生内存泄漏。
- 虚析构函数保障资源正确释放的原理:
- 虚析构函数利用C++的多态机制。当使用基类指针删除对象时,根据对象的实际类型(运行时类型),会调用相应的析构函数。在多层继承体系中,从最派生类的析构函数开始调用,然后依次调用其直接基类的析构函数,直到调用到基类的析构函数,这样就能保证每一层动态分配的资源都能被正确释放。
- 代码示例:
#include <iostream>
#include <cstring>
class Base {
public:
Base() {
data = new char[10];
std::strcpy(data, "Base");
}
// 非虚析构函数(错误示例)
// ~Base() {
// delete[] data;
// }
// 虚析构函数(正确示例)
virtual ~Base() {
delete[] data;
}
private:
char* data;
};
class Derived : public Base {
public:
Derived() {
moreData = new char[10];
std::strcpy(moreData, "Derived");
}
~Derived() {
delete[] moreData;
}
private:
char* moreData;
};
int main() {
Base* ptr = new Derived();
delete ptr;
return 0;
}
在上述代码中,如果Base
类的析构函数不是虚函数,当delete ptr
执行时,只会调用Base
类的析构函数,Derived
类中moreData
所指向的内存不会被释放。而将Base
类的析构函数声明为虚函数后,delete ptr
会先调用Derived
类的析构函数,释放moreData
,然后再调用Base
类的析构函数,释放data
,从而避免内存泄漏。