实现一个简单的智能指针模板shared_ptr和unique_ptr
C++11新特性的智能指针,是C++提供的最小垃圾回收的机制,shared_ptr
是一个模板,可以管理指针,并实现自动释放的效果,抹开标准库中shared_ptr
对于其它场景的思考, 其核心原理是引用——删除
机制,即对于对象的清理在于其引用的个数进行判断,如果没有对象引用这个堆空间,即count=0
的时候,就会将其释放。而unique_ptr
是独占, 无法拷贝和赋值,只能以移动语义传播,下面是一个简化版的Shared_ptr
和Unique_ptr
模板,用于理解shared_ptr
和unique_ptr
的运行原理
- 支持
get(), reset(), 解引用, ->运算符
等常用API - 没有考虑锁,只是用一个简单的counter字段来记录对
Shared_ptr
的引用
Shared_ptr
#include <iostream>
using namespace std;
template<class Ty>
class Shared_ptr{
public:
template<class ...ParametersTy>
explicit Shared_ptr(ParametersTy&&... args) noexcept :ty(new StoreTy())
{
ty->t = new Ty(forward<ParametersTy>(args)...);
}
explicit Shared_ptr(Ty* p) noexcept :ty(new StoreTy())
{
ty->t = p;
}
Shared_ptr(const Shared_ptr<Ty>& p) noexcept : ty(p.ty)
{
ty->count++;
}
~Shared_ptr() noexcept
{
if(flag){
ty->count--;
if(ty->count == 0)
{
delete ty->t;
delete ty;
}
}
}
size_t use_count() const { return ty->count; }
Ty* get(){return ty->t;}
void reset() noexcept
{
if(flag)
{
flag = false;
ty->count--;
if(ty->count == 0)
{
delete ty->t;
delete ty;
}
}
}
Ty* operator->(){return ty->t;}
private:
struct StoreTy{
Ty *t{nullptr};
int count{1};
};
bool flag{true};
StoreTy* ty;
};
struct Value1{
void print() { cout << "I am test type Value2\n"; }
};
int main()
{
Shared_ptr<Value1> p;
{
auto p1 = p;
p1->print();
p.reset();
cout<<"Use count "<<p.use_count()<<endl;
}
cout<<"Use count "<<p.use_count()<<endl;
}
Unique_ptr
- 支持
unique_ptr
特性的模板
#include <iostream>
using namespace std;
template<class Ty>
class Unique_ptr{
public:
template<class ...ParameterTy>
explicit Unique_ptr(ParameterTy&& ...args) noexcept : ty(new Ty(std::forward<ParameterTy>(args)...)){}
Unique_ptr(Unique_ptr&& ptr) noexcept : ty(ptr.ty)
{
ptr.ty = nullptr;
}
~Unique_ptr() noexcept {
if(ty) delete ty;
ty = nullptr;
}
Ty* get(){ return ty; }
Ty operator*(){ return *ty; }
Ty* operator->(){ return ty; }
void reset() noexcept
{
if(ty) delete ty;
ty = nullptr;
}
private:
Unique_ptr(const Unique_ptr<Ty>& p) = delete;
Unique_ptr<Ty> operator=(const Unique_ptr<Ty>& p) = delete;
Ty* ty;
};
int main(){
Unique_ptr<int> a(10);
Unique_ptr<int> c = std::move(a);
auto e = c; // 报错,不支持拷贝和赋值
}