您的位置:首页 > 其它

实现一个简单的shared_ptr

2016-05-30 14:22 344 查看
在看《effective C++》第3章时,基本上都是auto_ptr和shared_ptr的原理与应用。

auto_ptr和shared_ptr基本原理都是将构造好(new)的裸资源指针交给对象去打理,当对象释放时自动调用析构函数,在析构函数中delete裸资源指针;从而避免遗忘手动释放指针。

auto_ptr通过拷贝构造或者通过=赋值后,原来的auto_ptr就失效了(裸资源指针赋值为0),裸资源指针的所有权转移到新的auto_ptr对象中去了。

更多关于auto_ptr,参考我之前的总结“C++智能指针auto_ptr”。

在C++11中,auto_ptr已经被unique_ptr取代,关于unique_ptr,参考下“unique_ptr使用简介”。

shared_ptr通过引用计数(reference-counting smart pointer,RCSP),可以让多个智能指针对象同时拥有裸资源指针,只有在最后一个shared_ptr对象释放时,才会delete裸资源指针。
我在下面的代码中实现了一个简单的shared_ptr,后续看到模板部分再来补充吧。

#include<iostream>
#include<cassert>
using namespace std;

template <class T>
class shared_ptr
{
private:
T *_ptr;
int *pCount; //计数指针;
//int pCount; //如果用对象,每次初始化之后都是新的值;如果用static,则不同的智能指针会拥有相同的count。

public:
shared_ptr(T *p) : _ptr(p), pCount(new int(1)) //构造函数
{
}
shared_ptr(shared_ptr& another)
{
_ptr = another._ptr;

pCount = another.pCount; //浅拷贝,所有对象指向公有的 *pCount
++(*pCount);
}
T& operator *() //重载*操作符
{
return *_ptr;
}
T* operator ->() //重载->操作符
{
return _ptr;
}
int getCount() //获取引用计数
{
return *pCount;
}
~shared_ptr() //析构函数
{
(*pCount)--;
if(0 == *pCount)
{
delete _ptr;
delete pCount;
}
}
};

class Test
{
public:
Test()
{
cout<<"constructor of Test()"<<endl;
}
~Test()
{
cout<<"de-constructor of Test()"<<endl;
}
void helloTest()
{
cout<<"helloTest()"<<endl;
}
int v;
};

//入参和出参,分别会调用SmartPointer的拷贝构造函数和析构函数
//引用计数pCount也会分别+1和-1.
void testSmartPointer(shared_ptr<Test> sp)
{
cout<<sp.getCount()<<endl;
}

int main(void)
{
//构造一次,拷贝三次
Test *p = new Test;
shared_ptr<Test> s_p(p);
//shared_ptr<Test> s_p1(p); //错误,p会被多析构一次
shared_ptr<Test> s_p2(s_p);
shared_ptr<Test> s_p3(s_p2);
shared_ptr<Test> s_p4(s_p3);
s_p->helloTest();
(*s_p4).helloTest();

testSmartPointer(s_p4);

s_p->v = 10;
assert(s_p4->v == 10);

cout<<s_p4.getCount()<<endl;
assert(s_p.getCount() == s_p4.getCount());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: