MST

星途 面试题库

面试题:复杂继承体系下 C++ 类成员初始化异常处理策略

考虑一个复杂的 C++ 继承体系,基类和多个派生类都有各自需要初始化的成员变量,且这些成员变量初始化都可能抛出异常。请设计一套完整的异常处理策略,保证无论在哪一层成员初始化抛出异常,整个对象层次结构都能正确清理已分配资源,并给出相应的代码示例。
31.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在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;
}

异常处理策略

  1. RAII原则:每个类中的资源(如Resource)都使用智能指针(如std::unique_ptr)来管理。这样,当对象生命周期结束时,智能指针会自动释放其所管理的资源。
  2. try - catch块:在每个类的构造函数中使用try - catch块来捕获成员变量初始化时可能抛出的异常。如果捕获到异常,打印错误信息并重新抛出异常,确保上层调用者知道初始化失败。
  3. 自动清理:当异常被抛出时,C++的栈展开机制会自动调用已经构造的对象的析构函数,从而清理已分配的资源。例如,如果Derived类构造过程中derivedResource初始化失败,Base类的析构函数会被调用以清理baseResource

通过上述策略,可以保证无论在哪一层成员初始化抛出异常,整个对象层次结构都能正确清理已分配资源。