类结构设计与关键代码实现
#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;
}
工作原理解释
- 自定义删除器:在
A
和 B
类中分别定义了自定义删除器 ADeletor
和 BDeletor
。这些删除器负责在对象销毁时执行特殊的资源清理操作,如释放 GPU 内存。
- 智能指针选择:使用
std::unique_ptr
来管理 A
和 B
对象的生命周期,通过自定义删除器来确保正确的资源释放。同时,使用 std::weak_ptr
来处理 A
和 B
之间的相互引用关系。std::weak_ptr
不会增加对象的引用计数,因此可以避免循环引用导致的内存泄漏。
- 相互引用关系:
A
类中包含一个 std::weak_ptr<B>
成员 bWeakPtr
,B
类中包含一个 std::weak_ptr<A>
成员 aWeakPtr
。这样当 aPtr
和 bPtr
超出作用域时,它们各自管理的对象会被正确销毁,由于 weak_ptr
不会增加引用计数,不会出现循环引用导致的内存泄漏。同时,自定义删除器会在对象销毁时执行特殊的资源清理操作。