智能指針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)

發佈了76 篇原創文章 · 獲贊 16 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章