面试题答案
一键面试策略阐述
- 调用父类析构函数:在子类析构函数中,父类析构函数会被自动调用,无需显式调用。但如果父类析构函数不是虚函数,可能会导致析构不完整,所以父类析构函数应声明为虚函数。
- 处理内存泄漏:使用RAII(Resource Acquisition Is Initialization)机制,将动态分配的资源(如内存)封装在对象中,利用对象的生命周期来自动管理资源的释放。这样在对象销毁时,其析构函数会自动释放资源,避免内存泄漏。
- 处理异常情况:在构造函数和其他可能抛出异常的函数中,确保在异常抛出前已正确释放所有已分配的资源。使用try - catch块捕获异常,并在catch块中进行资源清理。
代码示例
#include <iostream>
#include <memory>
class Parent {
public:
Parent() {
data = new int[10];
std::cout << "Parent constructor" << std::endl;
}
virtual ~Parent() {
delete[] data;
std::cout << "Parent destructor" << std::endl;
}
private:
int* data;
};
class Child : public Parent {
public:
Child() {
try {
extraData = std::make_unique<int[]>(5);
std::cout << "Child constructor" << std::endl;
} catch(...) {
// 如果构造extraData失败,这里可以添加额外的清理逻辑
std::cerr << "Exception caught during Child construction" << std::endl;
throw;
}
}
~Child() {
std::cout << "Child destructor" << std::endl;
// 父类析构函数会自动被调用
}
private:
std::unique_ptr<int[]> extraData;
};
int main() {
try {
Child child;
} catch(...) {
std::cerr << "Exception propagated to main" << std::endl;
}
return 0;
}
在上述代码中:
Parent
类在构造函数中分配了动态内存,并在虚析构函数中释放。Child
类继承自Parent
,在构造函数中使用std::make_unique
分配内存,利用RAII机制在析构时自动释放。如果在Child
构造函数中分配extraData
时抛出异常,由于Parent
构造函数已成功执行,Parent
的析构函数会被自动调用以释放data
。同时,Child
类析构函数无需显式释放extraData
,因为std::unique_ptr
的析构函数会自动完成此操作。在main
函数中,使用try - catch
块捕获可能从Child
构造函数抛出的异常。