MST

星途 面试题库

面试题:C++ 智能指针:自定义删除器与循环引用问题的复杂场景处理

在一个复杂的图形渲染系统中,有多个对象存在相互引用关系(可能导致循环引用),并且每个对象的析构函数需要执行一些特殊的资源清理操作(如释放 GPU 内存),因此需要自定义删除器。请设计一个基于智能指针(shared_ptr 和 unique_ptr)的解决方案,既能避免循环引用导致的内存泄漏,又能正确执行每个对象的特殊资源清理操作。请给出完整的类结构设计和关键代码实现,并解释其工作原理。
36.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

类结构设计与关键代码实现

#include <memory>
#include <iostream>

// 前向声明
class B;

class A {
public:
    // 自定义删除器
    struct ADeletor {
        void operator()(A* a) const {
            std::cout << "释放 A 的 GPU 内存" << std::endl;
            delete a;
        }
    };
    std::weak_ptr<B> bWeakPtr;

    ~A() {
        std::cout << "A 的析构函数" << std::endl;
    }
};

class B {
public:
    // 自定义删除器
    struct BDeletor {
        void operator()(B* b) const {
            std::cout << "释放 B 的 GPU 内存" << std::endl;
            delete b;
        }
    };
    std::weak_ptr<A> aWeakPtr;

    ~B() {
        std::cout << "B 的析构函数" << std::endl;
    }
};

void test() {
    // 使用自定义删除器创建智能指针
    std::unique_ptr<A, A::ADeletor> aPtr(new A());
    std::unique_ptr<B, B::BDeletor> bPtr(new B());

    // 建立引用关系
    aPtr->bWeakPtr = bPtr;
    bPtr->aWeakPtr = aPtr;
}

工作原理解释

  1. 自定义删除器:在 AB 类中分别定义了自定义删除器 ADeletorBDeletor。这些删除器负责在对象销毁时执行特殊的资源清理操作,如释放 GPU 内存。
  2. 智能指针选择:使用 std::unique_ptr 来管理 AB 对象的生命周期,通过自定义删除器来确保正确的资源释放。同时,使用 std::weak_ptr 来处理 AB 之间的相互引用关系。std::weak_ptr 不会增加对象的引用计数,因此可以避免循环引用导致的内存泄漏。
  3. 相互引用关系A 类中包含一个 std::weak_ptr<B> 成员 bWeakPtrB 类中包含一个 std::weak_ptr<A> 成员 aWeakPtr。这样当 aPtrbPtr 超出作用域时,它们各自管理的对象会被正确销毁,由于 weak_ptr 不会增加引用计数,不会出现循环引用导致的内存泄漏。同时,自定义删除器会在对象销毁时执行特殊的资源清理操作。