MST

星途 面试题库

面试题:C++中RAII模式如何保证异常安全性

请简述在C++里RAII(Resource Acquisition Is Initialization)模式是怎样保证异常安全性的,并举一个简单的示例代码说明。
24.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. RAII保证异常安全性的原理

在C++中,RAII模式通过将资源的获取和释放与对象的生命周期绑定来保证异常安全性。当一个对象被创建时,它会获取所需的资源(例如内存、文件句柄、锁等)。当对象的生命周期结束时(无论是正常结束还是由于异常导致提前结束),其析构函数会自动释放这些资源。这就确保了在程序执行过程中,无论是否发生异常,资源都能被正确释放,避免了资源泄漏。

2. 示例代码

#include <iostream>
#include <memory>

// 自定义资源类
class Resource {
public:
    Resource() {
        std::cout << "Resource acquired" << std::endl;
    }
    ~Resource() {
        std::cout << "Resource released" << std::endl;
    }
};

// 使用RAII的类
class RAIIWrapper {
public:
    RAIIWrapper() : res(std::make_unique<Resource>()) {
        std::cout << "RAIIWrapper created" << std::endl;
    }
    ~RAIIWrapper() {
        std::cout << "RAIIWrapper destroyed" << std::endl;
    }
    // 模拟可能抛出异常的函数
    void doSomething() {
        std::cout << "Doing something..." << std::endl;
        throw std::runtime_error("Simulated exception");
    }

private:
    std::unique_ptr<Resource> res;
};

int main() {
    try {
        RAIIWrapper wrapper;
        wrapper.doSomething();
    } catch (const std::exception& e) {
        std::cerr << "Exception caught: " << e.what() << std::endl;
    }
    return 0;
}

在上述代码中,RAIIWrapper类持有一个std::unique_ptr<Resource>,当RAIIWrapper对象创建时,Resource对象被创建(资源获取),当RAIIWrapper对象生命周期结束(无论是正常结束还是由于异常),std::unique_ptr<Resource>的析构函数会释放Resource对象(资源释放)。在doSomething函数中抛出异常后,RAIIWrapper对象的析构函数依然会被调用,从而保证Resource资源被正确释放。