MST
星途 面试题库

面试题:C++ 智能指针异常处理与自定义删除器

假设你有一个使用 std::unique_ptr 管理的自定义资源类型,该资源需要特殊的释放操作(如关闭文件描述符并记录日志)。在可能抛出异常的函数中,如何结合自定义删除器来确保异常发生时资源的正确清理?请编写相应的代码示例。
48.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <memory>
#include <fstream>

// 自定义资源类型,这里假设是文件描述符(简化表示为int)
using FileDescriptor = int;

// 自定义删除器
struct FileDescriptorDeleter {
    void operator()(FileDescriptor* fd) const {
        if (fd) {
            // 关闭文件描述符(这里简化为打印)
            std::cout << "Closing file descriptor: " << *fd << std::endl;
            // 记录日志(这里简化为打印)
            std::ofstream logFile("resource_cleanup.log", std::ios::app);
            logFile << "File descriptor " << *fd << " has been closed." << std::endl;
            logFile.close();
            delete fd;
        }
    }
};

// 可能抛出异常的函数
void potentiallyThrowingFunction() {
    // 使用std::unique_ptr管理资源并结合自定义删除器
    std::unique_ptr<FileDescriptor, FileDescriptorDeleter> fileDescriptor(new FileDescriptor(42));

    // 模拟可能抛出异常的操作
    throw std::runtime_error("Some error occurred.");
}

int main() {
    try {
        potentiallyThrowingFunction();
    } catch (const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

在上述代码中:

  1. FileDescriptor 是自定义资源类型,这里简单地用 int 表示文件描述符。
  2. FileDescriptorDeleter 是自定义删除器,它定义了资源释放时要执行的操作,包括关闭文件描述符(打印表示)和记录日志。
  3. potentiallyThrowingFunction 函数中,使用 std::unique_ptr<FileDescriptor, FileDescriptorDeleter> 来管理 FileDescriptor 资源。这样,当函数因为异常退出时,std::unique_ptr 会调用自定义删除器 FileDescriptorDeleter 来正确清理资源。
  4. main 函数捕获可能抛出的异常并进行处理。