智能指针shared_ptr

boost库的第二类智能指针是shared_ptr。

shared_ptr的特点是:

一、 它可以指向相同的内容,靠引用计数来决定内容是否释放。其中new int申请的空间,在三个指向它的指针全部释放时才被释放,否则只是引用计数减一。

#include <cassert>
#include <boost/shared_ptr.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
	boost::shared_ptr<int> tmp(new int(50));
	boost::shared_ptr<int> a = tmp;
	boost::shared_ptr<int> b = tmp;
	
	*a = 100;

	assert(*b == 100);

	getchar();
	return 0;
}


二、 能作为容器元素来使用。

#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>

class counter
{
public:
	static int _no;
	counter()
	{
		_no++;
	}
	~counter()
	{
		_no--;
	}
	static void Speak()
	{
		std::cout << "Total " << _no << " Objects!" << std::endl;
	}
};
int counter::_no = 0;

int _tmain(int argc, _TCHAR* argv[])
{
	typedef boost::shared_ptr<counter> element;
	typedef std::vector<element> container;
	typedef std::vector<element>::iterator iterator;
	element a(new counter());
	element b(new counter());
	element c(new counter());
	element d(new counter());
	element e(new counter());
	container cr;
	cr.push_back(a);
	cr.push_back(b);
	cr.push_back(c);
	cr.push_back(d);
	cr.push_back(e);

	for (iterator it = cr.begin(); it != cr.end(); ++it)
	{
		(*it)->Speak();
	}

	cr.clear();

	getchar();
	return 0;
}


三、 shared_ptr可以定制删除器,来处理非delete和delete[]能够处理的资源,如示例中的文件描述符等。下面两个例子照抄说明书。

shared_ptr指向指针时,原来的指针调用方式为:&*sp,*sp表示是对象,&(*sp)代表是指针。可以用sp.get()来替代。

#include "boost/shared_ptr.hpp"
#include <vector>
#include <cassert>
#include <iostream>
#include <cstdio>

class FileCloser
{
public:
	void operator()(FILE* file)
	{
		std::cout << "The FileCloser has been called with a FILE*, which will now be closed.\n";
		if (file != 0)
		{
			std::fclose(file);
		}
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	{	// 在此作用域内文件打开会自动关闭
		FILE *f = std::fopen("test.txt", "r");
		if (f == 0)
		{
			std::cout << "Unable to open file\n";
			throw "Unable to open file";
		}
		boost::shared_ptr<FILE> sf(f, FileCloser());
		std::fseek(sf.get(), 100, SEEK_SET);
		std::fseek(&*sf, 100, SEEK_SET);
	}
	
	std::cout << std::endl;
}

第二个例子演示了安全删除器的方法,并且演示了删除函数的规则:实现operator()(TYPE *p){}函数。

#include "boost/shared_ptr.hpp"
#include <iostream>
class A 
{
	// 嵌套类
	class deleter 
	{    
	public:
		// 重载运算符()
		void operator()(A* p) 
		{        
			delete p;      
		}  
	};
	// 声明为友元类,再进行嵌套实现,实现了安全访问。
	friend class deleter;
public:  
	virtual void sing() 
	{    
		std::cout << "Lalalalalalalalalalala";  
	}
	// 构造器
	static boost::shared_ptr<A> createA() 
	{    
		boost::shared_ptr<A> p(new A(),A::deleter());
		return p;  
	}
protected:  
	virtual ~A() {};
};

int main() 
{
	// 构造函数创建出来一个类,然后直接调用,不用管理释放的任何操作。
	boost::shared_ptr<A> p=A::createA();
}


总结一下,shared_ptr的使用情况:

1 对一个对象无所有权的情况下,多次指针引用,这是哪个指针释放资源都会导致其他指针变成野指针,所以采用shared_ptr来规避这个问题,shared_ptr采用引用计数的方法只有在最后一个指针释放时才释放资源,其他情况只是引用计数减一。

2 它适用于容器类,正因为它有1的特性,才适用于容器类,这是与scoped_ptr很主要的特性区别。

3 它可以根据引用的内容来定制删除函数,有些情况下,delete和delete[]并不是注销资源的方式的时候,需要使用shared_ptr的定制删除函数的功能,删除规则和删除方法见示例代码。

4 shared_ptr很适用于对象没有所有权的情况下,所以特别适用于工厂类和构造器等设计模式,而且天生就为此实现。代码二可以创建一个构造器函数来实现每个对象的创建(自己可以修改一下)。

5 当要传送对象到库或从库获取对象,而没有明确的所有权时(这句话是资料上的原话,我没有理解具体的应用情况,照抄下来)

6 当管理一些需要特殊清除方式的资源时(这句话是资料上的原话,内容如3)

你可能感兴趣的:(智能指针shared_ptr)