MST
星途 面试题库

面试题:C++ 函数返回引用的异常安全性之基本场景分析

假设有一个类 `MyClass`,包含动态分配的资源(如 `int* data`),并且有一个函数 `MyClass& getMyClass()` 会返回 `MyClass` 实例的引用。在这个函数内部可能会抛出异常的情况下,如何保证返回引用的对象在异常发生时资源不泄漏?请给出代码示例并解释。
47.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在C++中,可以使用智能指针来管理动态分配的资源,以确保在异常发生时资源不泄漏。以下是实现代码示例及解释:

#include <memory>

class MyClass {
private:
    std::unique_ptr<int> data;
public:
    MyClass() : data(std::make_unique<int>(0)) {}

    ~MyClass() = default;

    // 拷贝构造函数和赋值运算符重载,根据需要实现
    MyClass(const MyClass& other) : data(std::make_unique<int>(*other.data)) {}
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            data = std::make_unique<int>(*other.data);
        }
        return *this;
    }
};

MyClass& getMyClass() {
    static std::unique_ptr<MyClass> instance;
    if (!instance) {
        try {
            instance.reset(new MyClass());
        } catch(...) {
            // 这里可以进行异常处理,例如记录日志等
            throw;
        }
    }
    return *instance;
}

解释:

  1. 资源管理:在 MyClass 类中,使用 std::unique_ptr<int> 来管理动态分配的 int 类型资源 datastd::unique_ptr 是C++标准库提供的智能指针,在其生命周期结束时会自动释放所管理的资源,这确保了在 MyClass 对象销毁时,data 所指向的内存会被自动释放,即使在异常情况下也不例外。

  2. 函数实现:在 getMyClass 函数中,使用一个静态的 std::unique_ptr<MyClass> 来保存 MyClass 的实例。这样可以保证整个程序中只有一个 MyClass 实例(单例模式的一种变体)。当首次调用 getMyClass 时,instance 为空,此时尝试创建 MyClass 实例。如果创建过程中抛出异常,std::unique_ptr 会自动释放已分配的资源,从而避免内存泄漏。同时,在异常捕获块中,可以根据需要进行异常处理,然后重新抛出异常,让调用者决定如何处理。

通过上述方式,确保了在 getMyClass 函数内部抛出异常时,返回引用的 MyClass 对象的资源不会泄漏。