智能指针(二):shared_ptr实现原理

前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针,顾名思义,有个shared表明共享嘛.所以shared_ptr类型的智能指针可以做为STL容器的元素

下面我们来瞧瞧shared_ptr具体是咋实现的.相较auto_ptr有下面几个不同的地方:


1.引进了一个计数器shared_count,用来表示当前有多少个智能指针对象共享指针指向的内存块

2.析构函数中不是直接释放指针对应的内存块,如果shared_count大于1则不释放内存只是将引用计数减1,只是计数等于1时释放内存

3.复制构造与赋值操作符只是提供一般意义上的复制功能,并且将引用计数加1.

shared_ptr实现代码


#include<iostream>
#include<memory>
using namespace std;
/*
class for counted reference semantics
deletes the object to which it refers when the last CountedPtr
that refers to it is destroyed
*/

template <class T>

class CountedPtr 
{
private:
	T* ptr;        // pointer to the value
	long* count;   // shared number of owners
public:
	//initialize pointer with existing pointer
	//-requires that the pointer p is a return value of new
	explicit CountedPtr(T* p = 0)
		: ptr(p), count(new long(1)) 
	{

	}

	//copy pointer (one more owner)
	CountedPtr(const CountedPtr& p) throw()
		: ptr(p.ptr), count(p.count)
	{
		++*count;
	}

	//destructor (delete value if this was the last owner)

	~CountedPtr() throw() 
	{
		dispose();
	}

	//assignment (unshare old and share new value)
	CountedPtr & operator= (CountedPtr & p) throw()
	{
		if (this != &p) 
		{
			dispose();
			ptr = p.ptr;
			count = p.count;
			++*count;
		}
		return *this;
	}

	//access the value to which the pointer refers
	T& operator*() const throw()
	{
		return *ptr;
	}

	T* operator->() const throw()
	{
		return ptr;
	}
private:
	void dispose() 
	{
		if (--*count == 0)
		{
			delete count;
			delete ptr;
		}
	}

};

class A
{
public:

	A()  
	{
		cout << "A CONSTRUCT!" << endl;
	}

	~A() 
	{
		cout << "A DESSTRUCT!" << endl;
	}

	CountedPtr<A> m_ptr;
};
class CLeader;
class CMember;

class CLeader
{
public:
	CLeader() 
	{ 
		cout << "CLeader::CLeader()" << endl; 
	}
	~CLeader() 
	{ 
		cout << "CLeader:;~CLeader() " << endl;
	}

	CountedPtr<CMember> member;
};

class CMember
{
public:
	CMember() 
	{ 
		cout << "CMember::CMember()" << endl; 
	}
	~CMember()
	{ 
		cout << "CMember::~CMember() " << endl; 
	}

	CountedPtr<CLeader> leader;
};

void TestSharedPtrCrossReference()
{
	cout << "TestCrossReference<<<" << endl;
	CountedPtr<CLeader> ptrleader(new CLeader);
	CountedPtr<CMember> ptrmember(new CMember);

	ptrleader->member = ptrmember;
	ptrmember->leader = ptrleader;

}


int main()
{
	//循环引用,引发内存泄露
	CountedPtr<A> ap1(new A());
	ap1->m_ptr = ap1;
	//循环引用,引发内存泄露
	TestSharedPtrCrossReference();

	CountedPtr<int>ap2(new int(1));
	CountedPtr<int>ap3(ap2);//ap2任然拥有所有权

	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值