MST

星途 面试题库

面试题:C++构造函数异常处理与资源管理

假设你正在开发一个使用动态内存分配(如`new`操作符)的类,在构造函数中分配内存时可能会抛出异常。请描述如何在构造函数异常处理的同时,有效地管理动态分配的资源,避免内存泄漏。并给出相关代码示例。
46.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 资源管理方法
    • 使用智能指针(如std::unique_ptrstd::shared_ptr)来管理动态分配的资源。智能指针会在其生命周期结束时自动释放所管理的资源,从而避免内存泄漏。
    • 在构造函数中,如果资源分配成功,将其存储在智能指针中。如果在构造过程中抛出异常,智能指针会自动清理已分配的资源。
  2. 代码示例
#include <memory>
#include <iostream>

class MyClass {
private:
    std::unique_ptr<int[]> data;
    int size;
public:
    MyClass(int n) : size(n) {
        try {
            data = std::make_unique<int[]>(n);
            // 假设这里可以进行其他初始化操作
            for (int i = 0; i < n; ++i) {
                data[i] = i;
            }
        } catch (const std::bad_alloc& e) {
            std::cerr << "内存分配失败: " << e.what() << std::endl;
            throw; // 重新抛出异常,让调用者处理
        }
    }
    // 不需要显式的析构函数,因为std::unique_ptr会自动处理资源释放
    // ~MyClass() {
    //     // 如果没有使用智能指针,需要在这里手动释放内存
    //     // delete[] data;
    // }
    void printData() const {
        for (int i = 0; i < size; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    try {
        MyClass obj(5);
        obj.printData();
    } catch (const std::exception& e) {
        std::cerr << "捕获到异常: " << e.what() << std::endl;
    }
    return 0;
}

在上述代码中:

  • MyClass类使用std::unique_ptr<int[]>来管理动态分配的整数数组。
  • 在构造函数中,使用std::make_unique<int[]>(n)分配内存。如果分配失败,std::make_unique会抛出std::bad_alloc异常,此时智能指针data不会获得有效的资源,并且在构造函数结束时(由于异常),不会尝试释放无效资源。
  • 由于使用了std::unique_ptr,不需要显式定义析构函数来释放资源。
  • main函数中,通过try - catch块捕获可能的异常,并进行相应处理。