面试题答案
一键面试在C++中处理复杂继承体系下成员变量初始化异常并正确清理资源,可以使用RAII(Resource Acquisition Is Initialization)原则结合try - catch块来实现。以下是一个示例:
#include <iostream>
#include <memory>
// 模拟资源类,使用RAII管理资源
class Resource {
public:
Resource() {
std::cout << "Resource acquired" << std::endl;
}
~Resource() {
std::cout << "Resource released" << std::endl;
}
};
class Base {
private:
std::unique_ptr<Resource> baseResource;
public:
Base() {
try {
baseResource = std::make_unique<Resource>();
std::cout << "Base initialized" << std::endl;
} catch(...) {
std::cout << "Base initialization failed, cleaning up" << std::endl;
throw;
}
}
~Base() {
std::cout << "Base destructed" << std::endl;
}
};
class Derived : public Base {
private:
std::unique_ptr<Resource> derivedResource;
public:
Derived() {
try {
derivedResource = std::make_unique<Resource>();
std::cout << "Derived initialized" << std::endl;
} catch(...) {
std::cout << "Derived initialization failed, cleaning up" << std::endl;
throw;
}
}
~Derived() {
std::cout << "Derived destructed" << std::endl;
}
};
int main() {
try {
Derived d;
} catch(...) {
std::cout << "Exception caught in main" << std::endl;
}
return 0;
}
异常处理策略
- RAII原则:每个类中的资源(如
Resource
)都使用智能指针(如std::unique_ptr
)来管理。这样,当对象生命周期结束时,智能指针会自动释放其所管理的资源。 - try - catch块:在每个类的构造函数中使用try - catch块来捕获成员变量初始化时可能抛出的异常。如果捕获到异常,打印错误信息并重新抛出异常,确保上层调用者知道初始化失败。
- 自动清理:当异常被抛出时,C++的栈展开机制会自动调用已经构造的对象的析构函数,从而清理已分配的资源。例如,如果
Derived
类构造过程中derivedResource
初始化失败,Base
类的析构函数会被调用以清理baseResource
。
通过上述策略,可以保证无论在哪一层成员初始化抛出异常,整个对象层次结构都能正确清理已分配资源。