1. 程式人生 > >c++智慧指標unqiue_ptr

c++智慧指標unqiue_ptr

基本分類

在C++中智慧指標有四種,分別是auto_ptr,shared_ptr,unique_ptr,weak_ptr。其中auto_ptr已經被捨棄,不在累述。大約可以分為兩類:

  • 一種是獨佔式擁有,即同一時間內只有一個智慧指標可以指向該物件。但是你可以移交擁有權,它對於避免資源洩露,例如“以new建立物件後因為異常發生而忘記呼叫delete,特別有用”。
  • 二是共享式擁有,多個智慧指標可以指向相同物件,該物件會在最後一個reference被銷燬時,被釋放,即計數器為0時。問了能在結構較複雜的情境下工作,標準庫提供了weak-普通人,bad_weak_ptr,enable_shared_from_this等輔助類。

標頭檔案 所有智慧指標的標頭檔案都是

unique_ptr

unique_ptr 是為了保證在異常情況下解構函式被成功呼叫。字面上的意思就是unique_ptr是“其所指物件”的唯一擁有者。使用unique_ptr的充要條件就是他所指的物件只有一個擁有著。

 #include <string>
#include <iostream>
#include <memory>
#include <cassert>
using namespace std;
class Object
{
public:
	Object(int a):m_a(a)
	{
		cout << "建構函式被呼叫" << endl;
	}
	~Object()
	{
		cout << "解構函式被呼叫" << endl;
	}
	Object(const Object&& rhs)
	{
		cout << "移動建構函式被呼叫" << endl;
	}
	void say()
	{
		cout << "say" << m_a << endl;
	}
	int m_a;
};
typedef std::unique_ptr<Object> UniqueObjectPtr;
void print(const UniqueObjectPtr& rhs) { cout << "print" << endl; }
void transfer(UniqueObjectPtr obj) {
	//一旦呼叫該函式,如果該函式不在轉移擁有權,物件會在函式結束時delete調
	cout << "transfer" << obj->m_a << endl; 
	}
UniqueObjectPtr source(UniqueObjectPtr obj)
{
	cout << "source" << endl;
	return obj; // 不在需要呼叫std::move,此處已將許可權返回,是因為語言的規定
}
int main()
{
	//UniqueObjectPtr up = new Object; 無法編譯成功,因為必須直接初始化
	UniqueObjectPtr up(new Object(5));//直接初始化
	/*auto p = up.get(); //返回被儲存的point的地址
	if (nullptr == p)
	{
		return -1;
	}*/
	if (up)
	{
		cout << "智慧指標存在" << endl;
	}
	//print(up);
	up->say();
	//UniqueObjectPtr up1 = up; //同時只能有一個擁有該物件
	UniqueObjectPtr up1(std::move(up));//使用std::move移交物件的所有權
	up1->say();

	//transfer(up1);//同時只能有一個擁有該物件,無法編譯成功,有臨時物件obj
	//transfer(std::move(up1));//需要將管理權移交給臨時物件obj,up1會被置NULL
	//cout << up1->m_a << endl; 在std::move(up1)移交之後,在此呼叫時,會導致程式崩潰
	//assert(NULL == up1);
	UniqueObjectPtr up2(std::move(source(std::move(up1))));
	std::shared_ptr<Object> sh(std::move(up2)); //將控制權移交給shaed_ptr管理,up1會被置NULl
	assert(NULL == up1);
};

當定義一個array陣列時,或者需要定義自定義刪除時,需要重寫自己的Deleter,可以借用lambda,模式如下std::unique_ptr<T,void()(T)>;

#include <string>
#include <iostream>
#include <memory>
using namespace std;


int main()
{
	//模板為std::unique_ptr<T,void(*)(T*)>;
	std::unique_ptr<int, void(*)(int*)> up(new int[10], 
						[](int*p){cout << "解構函式被呼叫 "<< endl;
						delete[] p; });
};