shared_ptr采用对象管理资源,通过引用计数自动控制资源的释放时机。
实现时需要注意:
- 一个shared_ptr对象具有两个裸指针,这点通过sizeof可简单确定。其中,一个裸指针用于管理使用时分配的资源(实例中
_ptr
);另一个用于记录对象信息(示例中_ref
) - 用于记录对象信息的结构体至少包含两个引用计数,即(正常的)引用计数(示例中
shared_count
)和弱引用计数(示例中weak_count
),二者均为原子类型。_ptr所分配的资源是否释放只与shared_count的值有关
#include <iostream>
#include <atomic>
struct Ref
{
Ref():shared_count(1), weak_count(0){}
std::atomic<int> shared_count;
std::atomic<int> weak_count;
};
template <typename T>
class SharedPtr {
public:
SharedPtr(T *p = nullptr) {
_ptr = p;
_ref = new Ref();
}
SharedPtr(const SharedPtr<T> &rv) {
_ptr = rv._ptr;
_ref = rv._ref;
AddRefCount();
}
SharedPtr<T>& operator=(const SharedPtr<T>& rv) {
if (_ptr != rv._ptr) {
Release();
_ptr = rv._ptr;
_ref = rv._ref;
AddRefCount();
}
return *this;
}
~ SharedPtr() {
Release();
}
T& operator *() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
T* get() {
return _ptr;
}
int UseCount() {
return _ref->shared_count;
}
private:
void AddRefCount() {
++ _ref->shared_count;
}
void Release() {
if (--_ref->shared_count == 0) {
delete _ptr;
delete _ref;
}
}
private:
T *_ptr;
Ref *_ref;
};