boost___smart_ptr

包括scoped_ptr, scoped_array, shared_ptr, shared_array, weak_ptr, intrusive_ptr六個部分。

scoped_ptr很類似std::auto_ptr,但是其所有權更加嚴格,一旦獲得不允許轉讓。

複製代碼
 1 namespace boost {
2 template<typename T> class scoped_ptr : noncopyable {
3 public:
4 explicit scoped_ptr(T* p = 0);
5 ~scoped_ptr();
6
7 void reset(T* p = 0);
8
9 T& operator*() const;
10 T* operator->() const;
11 T* get() const;
12
13 void swap(scoped_ptr& b);
14 };
15
16 template<typename T>
17 void swap(scoped_ptr<T> & a, scoped_ptr<T> & b);
18 }
複製代碼

成員函數

explicit scoped_ptr(T* p=0)

構造函數,存儲p的一份拷貝。注意,p 必須是用operator new分配的,或者是null.在構造的時候,不要求T必須是一個完整的類型。當指針p是調用某個分配函數的結果而不是直接調用new得到的時候很有用:因爲這個類型不必是完整的,只需要類型T的一個前向聲明就可以了。這個構造函數不會拋出異常。

~scoped_ptr()

刪除指針所指向的對象。類型T在被銷燬時必須是一個完整的類型。如果scoped_ptr在它被析構時並沒有保存資源,它就什麼都不做。這個析構函數不會拋出異常。

void reset(T* p=0);

重置一個 scoped_ptr 就是刪除它已保存的指針,如果它有的話,並重新保存p. 通常,資源的生存期管理應該完全由scoped_ptr自己處理,但是在極少數時候,資源需要在scoped_ptr的析構之前釋放,或者scoped_ptr要處理它原有資源之外的另外一個資源。這時,就可以用reset,但一定要儘量少用它。(過多地使用它通常表示有設計方面的問題) 這個函數不會拋出異常。

T& operator*() const;

該運算符返回一個智能指針中存儲的指針所指向的對象的引用。由於不允許空的引用,所以解引用一個擁有空指針的scoped_ptr將導致未定義行爲。如果不能肯定所含指針是否有效,就用函數get替代解引用。這個函數不會拋出異常。

T* operator->() const;

返回智能指針所保存的指針。如果保存的指針爲空,則調用這個函數會導致未定義行爲。如果不能肯定指針是否空的,最好使用函數get。這個函數不會拋出異常。

T* get() const;

返回保存的指針。應該小心地使用get,因爲它可以直接操作裸指針。但是,get使得你可以測試保存的指針是否爲空。這個函數不會拋出異常。get通常在調用那些需要裸指針的函數時使用。

operator unspecified_bool_type() const

返回scoped_ptr是否爲非空。返回值的類型是未指明的,但這個類型可被用於Boolean的上下文(boolean context)中。在if語句中最好使用這個類型轉換函數,而不要用get去測試scoped_ptr的有效性

void swap(scoped_ptr& b)

交換兩個scoped_ptr的內容。這個函數不會拋出異常。

普通函數

template<typename T> void swap(scoped_ptr<T>& a,scoped_ptr<T>& b)

這個函數提供了交換兩個scoped pointer的內容的更好的方法。之所以說它更好,是因爲 swap(scoped1,scoped2) 可以更廣泛地用於很多指針類型,包括裸指針和第三方的智能指針。scoped1.swap(scoped2) 則只能用於它的定義所在的智能指針,而不能用於裸指針。

用法

scoped_ptr的用法與普通的指針沒什麼區別;最大的差別在於你不必再記得在指針上調用delete,還有複製是不允許的。典型的指針操作(operator* 和 operator->)都被重載了,並提供了和裸指針一樣的語法。用scoped_ptr和用裸指針一樣快,也沒有大小上的增加,因此它們可以廣泛使用。使用boost::scoped_ptr時,包含頭文件"boost/scoped_ptr.hpp". 在聲明一個scoped_ptr時,用被指物的類型來指定類模板的參數。例如,以下是一個包含std::string指針的scoped_ptr:

boost::scoped_ptr<std::string> p(new std::string("Hello"));

當scoped_ptr被銷燬時,它對它所擁有的指針調用delete 。

複製代碼
 1 int main()
2 {
3 boost::scoped_ptr<string> sp(new string("hello world!"));
4 cout<<*sp<<endl;
5 cout<<sp->size()<<endl;
6
7 *sp = "hekexin";
8 cout<<*sp<<endl;
9 cout<<sp->size()<<endl;
10
11 //重置一個 scoped_ptr 就是刪除它已保存的指針,如果它有的話,
12 //並重新保存p. 通常,資源的生存期管理應該完全由scoped_ptr自己處理,
13 //但是在極少數時候,資源需要在scoped_ptr的析構之前釋放,或者scoped_ptr
14 //要處理它原有資源之外的另外一個資源。這時,就可以用reset,但一定要盡
15 //量少用它。(過多地使用它通常表示有設計方面的問題) 這個函數不會拋出異常。
16 sp.reset();
17 assert(sp.get() == 0);
18 assert(sp == 0);
19 assert(!sp);
20
21 return 0;
22 }
複製代碼

 

scoped_array: 包裝了new[]而不是new,爲動態數組提供了代理。與scoped_ptr設計思想一致,不能賦值,拷貝,只能在被聲明的作用域內使用。接口也大體相同,特點:

1. 構造函數接受的指針必須是new []的結果或者0.

2. 沒有* ->重載操作符,因爲持有的不是一個普通指針。

3. 提供了[]重載操作符,像普通數組一樣用下表訪問。

4. 沒有begin(), end()等類似容器的迭代器操作。

其實還是儘量少動態分配數組,儘量用vector替代。

複製代碼
int main()
{
boost::scoped_array<int> sap(new int[100]);
std::fill_n(&sap[0], 100, 5);
sap[0] = sap[2] + sap[3];

for (int i=0; i<100; ++i)
{
cout<<sap[i]<<endl;
}

return 0;
}
複製代碼

shared_ptr非常有用,引用計數的引入,使其可以賦值,拷貝和任意的共享,也可以存放在容器中。

 

複製代碼
 1 int main()
2 {
3 shared_ptr<int> sp(new int(10));
4 cout<<*sp<<endl;
5 assert(sp.unique());
6
7 shared_ptr<int> sp2 = sp;
8 assert(sp == sp2 && sp.use_count() == 2);
9 *sp = 100;
10 assert(!sp.unique());
11 cout<<*sp2<<endl;
12
13 sp.reset();
14 assert(!sp);
15 cout<<*sp2<<endl;
16 cout<<sp2.use_count()<<endl;
17
18 return 0;
19 }
複製代碼

 

複製代碼
 1 class Shared
2 {
3 private:
4 shared_ptr<int> sp_;
5
6 public:
7 Shared(shared_ptr<int> p) : sp_(p) {}
8 void print()
9 {
10 cout<<"use count : "<<sp_.use_count()<<" val : "<<*sp_<<endl;
11 }
12 void print_func(shared_ptr<int> sp)
13 {
14 cout<<"use count : "<<sp.use_count()<<" val : "<<*sp<<endl;
15 }
16
17 void print_func1(shared_ptr<int>& sp)
18 {
19 cout<<"use count : "<<sp.use_count()<<" val : "<<*sp<<endl;
20 }
21 };
22
23 int main()
24 {
25 shared_ptr<int> sp(new int(100));
26 Shared s1(sp);
27 Shared s2(sp);
28 s1.print(); // 3, 100
29 s2.print(); // 3, 100
30
31 *sp = 200;
32 s1.print(); //3, 200
33 s2.print(); //3, 200
34
35 s1.print_func(sp); // 4, 200
36
37 s1.print(); // 3, 200
38
39 s1.print_func1(sp); //3, 200
40
41 return 0;
42 }
複製代碼

 

複製代碼
 1 int main()
2 {
3 shared_ptr<string> sp = make_shared<string>("hello world!");
4 shared_ptr< vector<int> > spv = make_shared< vector<int> >(10, 3);
5 assert(*sp == "hello world!");
6 assert(sp.unique());
7 assert(spv->size() == 10);
8 vector<int>& vec = *spv;
9
10 typedef vector<shared_ptr<int> > vs;
11 vs spVec(10);
12 cout<<spVec.size()<<endl;
13 int i = 0;
14 for (vs::iterator ite = spVec.begin(); ite != spVec.end(); ++ite)
15 {
16 *ite = make_shared(++i);
17
18 }
19 return 0;
20 }
複製代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章