智能指针
2025/11/20大约 3 分钟
智能指针
ast 项目提供了三种智能指针实现,用于安全地管理对象生命周期,避免内存泄漏和悬空指针问题。
SharedPtr
共享指针实现,类似于 C++ 标准库的 std::shared_ptr,通过引用计数机制实现资源共享。
重要限制
SharedPtr只能用于继承自Object类型的类,因为它依赖于Object基类提供的引用计数方法(incRef()和decRef())。
主要特点
- 支持多个指针指向同一对象,通过引用计数管理对象生命周期
- 当最后一个引用被销毁时,对象会被正确释放
- 提供自动类型转换和箭头操作符重载
核心方法
| 方法 | 描述 |
|---|---|
| 构造函数 | 支持默认构造、通过原始指针构造和拷贝构造 |
| 析构函数 | 减少引用计数,必要时释放对象 |
operator= | 赋值运算符重载,支持从其他 SharedPtr 或原始指针赋值 |
operator-> | 提供对被管理对象的成员访问 |
get() | 获取原始指针 |
使用示例
#include "AstUtil/SharedPtr.hpp"
#include "AstUtil/Object.hpp"
class MyObject: public _AST Object
{
public:
void doSomething(){/* todo: implement functionality */}
};
int main()
{
AST_USING_NAMESPACE
// 创建共享指针对象(只能用于Object的子类)
SharedPtr<MyObject> ptr1 = new MyObject(); // MyObject必须继承自Object
// 共享所有权
SharedPtr<MyObject> ptr2 = ptr1;
// 访问对象成员
ptr1->doSomething();
// 获取原始指针
MyObject* rawPtr = ptr1.get();
}ScopedPtr
作用域指针,用于管理单一所有权的资源,生命周期严格限制在作用域内。
主要特点
- 独占所有权,禁止复制和赋值操作
- 作用域结束时自动释放资源
- 提供自定义删除器,对Object类型有特殊处理(调用
destruct()方法) - 可以用于普通类型和Object的子类
核心方法
| 方法 | 描述 |
|---|---|
| 构造函数 | 支持默认构造和通过原始指针构造 |
| 析构函数 | 自动释放管理的资源 |
reset() | 重置指针,释放原有资源并接管新资源 |
get() | 获取原始指针 |
使用示例
#include "AstUtil/ScopedPtr.hpp"
#include "AstUtil/Object.hpp"
class MyObject: public _AST Object
{
public:
void doSomething(){/* todo: implement functionality */}
};
int main()
{
AST_USING_NAMESPACE
{
// 作用域开始
// 可以用于普通类型
ScopedPtr<int> intPtr(new int(42));
// 也可以用于Object子类(有特殊的删除处理)
ScopedPtr<MyObject> objPtr(new MyObject()); // MyObject必须继承自Object
objPtr->doSomething();
// 重置指针
objPtr.reset(new MyObject());
// 作用域结束时自动释放
}
}WeakPtr
弱引用指针,类似于 C++ 标准库的 std::weak_ptr,不增加引用计数,避免循环引用问题。
重要限制
WeakPtr只能用于继承自Object类型的类,因为它依赖于Object基类提供的弱引用计数方法(incWeakRef()、decWeakRef())和销毁状态检查(isDestructed())。
主要特点
- 不影响对象的生命周期,只增加弱引用计数
- 可以检测对象是否已被销毁
- 提供访问对象的安全机制
核心方法
| 方法 | 描述 |
|---|---|
| 构造函数 | 支持默认构造、通过原始指针构造和拷贝构造 |
| 析构函数 | 减少弱引用计数 |
operator= | 赋值运算符重载 |
lock() | 获取原始指针(不检查对象是否已销毁) |
get() | 安全获取指针,检查对象是否已销毁 |
使用示例
#include "AstUtil/WeakPtr.hpp"
#include "AstUtil/SharedPtr.hpp"
#include "AstUtil/Object.hpp"
class MyObject: public _AST Object
{
public:
void doSomething(){/* todo: implement functionality */}
};
int main()
{
AST_USING_NAMESPACE
// 创建共享指针(只能用于Object的子类)
SharedPtr<MyObject> shared = new MyObject(); // MyObject必须继承自Object
// 创建弱引用指针
WeakPtr<MyObject> weak = shared.get();
// 安全访问对象
if (MyObject* obj = weak.get()) {
obj->doSomething();
}
}智能指针的使用建议
- 优先使用 ScopedPtr:当资源仅在一个作用域内使用时
- 使用 SharedPtr:当需要多个指针共享同一资源时(仅适用于Object的子类)
- 使用 WeakPtr:当需要引用共享资源但不希望影响其生命周期时(仅适用于Object的子类),特别是避免循环引用
- 避免原始指针:尽可能使用智能指针替代原始指针管理动态资源
- 注意类型安全:确保智能指针的模板类型与实际管理的对象类型匹配,特别注意SharedPtr和WeakPtr只能用于Object的子类