MST

星途 面试题库

面试题:C++ 异常处理中引用和指针的资源管理

假设你正在开发一个涉及大量资源(如文件句柄、网络连接等)管理的 C++ 程序,在使用引用和指针的场景下,如何合理地结合异常处理来确保资源的正确释放,避免内存泄漏和资源泄漏?请以代码示例说明你会采用哪些设计模式或编程技巧。
35.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在 C++ 中,处理资源管理并结合异常处理以避免泄漏,可以使用智能指针和 RAII(Resource Acquisition Is Initialization)技术。以下以文件句柄为例进行说明:

  1. 使用 std::unique_ptr 和 RAII
#include <iostream>
#include <memory>
#include <fstream>

class FileRAII {
public:
    FileRAII(const std::string& filename) : file(std::make_unique<std::ifstream>(filename)) {
        if (!file->is_open()) {
            throw std::runtime_error("Failed to open file");
        }
    }

    ~FileRAII() = default;

    std::ifstream& getFile() {
        return *file;
    }

private:
    std::unique_ptr<std::ifstream> file;
};

void processFile(const std::string& filename) {
    try {
        FileRAII fileRAII(filename);
        std::ifstream& file = fileRAII.getFile();
        // 处理文件
        std::string line;
        while (std::getline(file, line)) {
            std::cout << line << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
}

在上述代码中:

  • FileRAII 类使用 std::unique_ptr<std::ifstream> 来管理文件句柄,利用 RAII 机制,在对象构造时获取资源(打开文件),在对象析构时释放资源(关闭文件)。
  • 如果文件打开失败,构造函数抛出异常,由于 std::unique_ptr 的存在,不会造成文件句柄泄漏。
  1. 使用 std::shared_ptr(适用于需要共享资源所有权的场景)
#include <iostream>
#include <memory>
#include <fstream>

class FileSharedRAII {
public:
    FileSharedRAII(const std::string& filename) : file(std::make_shared<std::ifstream>(filename)) {
        if (!file->is_open()) {
            throw std::runtime_error("Failed to open file");
        }
    }

    std::shared_ptr<std::ifstream> getFile() {
        return file;
    }

private:
    std::shared_ptr<std::ifstream> file;
};

void processSharedFile(const std::string& filename) {
    try {
        FileSharedRAII fileSharedRAII(filename);
        std::shared_ptr<std::ifstream> file = fileSharedRAII.getFile();
        // 处理文件
        std::string line;
        while (std::getline(*file, line)) {
            std::cout << line << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
}

这里 FileSharedRAII 类使用 std::shared_ptr<std::ifstream>,适用于多个对象需要共享文件句柄所有权的场景。std::shared_ptr 通过引用计数来管理资源的生命周期,当引用计数为 0 时,自动释放资源。

总结:

  • RAII 原则:通过将资源管理封装在对象中,利用对象的构造和析构函数来获取和释放资源。
  • 智能指针std::unique_ptr 用于独占资源所有权,std::shared_ptr 用于共享资源所有权,它们都能在异常发生时确保资源正确释放,避免泄漏。

对于网络连接等其他资源,也可以采用类似的方式,将资源包装在 RAII 对象中,使用智能指针管理资源的生命周期。