【Boost】boost库中智能指针概述
這篇文章主要介紹 boost中的智能指針的使用。
??? 內(nèi)存管理是一個(gè)比較繁瑣的問題,C++中有兩個(gè)實(shí)現(xiàn)方案: 垃圾回收機(jī)制和智能指針。垃圾回收機(jī)制因?yàn)樾阅艿仍虿槐籆++的大佬們推崇, 而智能指針被認(rèn)為是解決C++內(nèi)存問題的最優(yōu)方案。
1. 定義
???? 一個(gè)智能指針就是一個(gè)C++的對象, 這對象的行為像一個(gè)指針,但是它卻可以在其不需要的時(shí)候自動刪除。注意這個(gè)“其不需要的時(shí)候”, 這可不是一個(gè)精確的定義。這個(gè)不需要的時(shí)候可以指好多方面:局部變量退出函數(shù)作用域、類的對象被析構(gòu)……。所以boost定義了多個(gè)不同的智能指針來管理不同的場景。
| shared_ptr<T> | 內(nèi)部維護(hù)一個(gè)引用計(jì)數(shù)器來判斷此指針是不是需要被釋放。是boost中最常用的智能指針了。 |
| scoped_ptr<t> | 當(dāng)這個(gè)指針的作用域消失之后自動釋放 |
| intrusive_ptr<T> | 也維護(hù)一個(gè)引用計(jì)數(shù)器,比shared_ptr有更好的性能。但是要求T自己提供這個(gè)計(jì)數(shù)器。 |
| weak_ptr<T> | 弱指針,要和shared_ptr 結(jié)合使用 |
| shared_array<T> | 和shared_ptr相似,但是訪問的是數(shù)組 |
| scoped_array<T> | 和scoped_ptr相似,但是訪問的是數(shù)組 |
2. Boost::scoped_ptr<T>
??? scoped_ptr 是boost中最簡單的智能指針。scoped_ptr的目的也是很簡單, 當(dāng)一個(gè)指針離開其作用域時(shí)候,釋放相關(guān)資源。特別注意的一定就是scoped_ptr 不能共享指針的所有權(quán)也不能轉(zhuǎn)移所有權(quán)。也就是說這個(gè)內(nèi)存地址就只能給的聲明的變量用,不能給其他使用。
??? 下面是scoped_ptr的幾個(gè)特點(diǎn):
1 class test
2 {
3 public:
4 void print()
5 {
6 cout << "test print now" <<endl;
7 }
8 };
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 boost::scoped_ptr<test> x(new test);
12 x->print();
13 return 0;
14 }
3.Boost::shared_ptr<T>
??? shared_ptr 具有如下幾個(gè)特點(diǎn):
我們可以看下如下例子:
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> ptr_1(new test);
4 ptr_1->print();//引用計(jì)數(shù)為1
5 boost::shared_ptr<test> ptr_2 = ptr_1;
6 ptr_2->print();//引用計(jì)數(shù)為2
7 ptr_1->print();// 引用計(jì)數(shù)還是為2
8 return 0;
9 }
4. Boost::intrusive_ptr<T>
??? intrusive_ptr 的主要和share_ptr一樣, 對比share_ptr,其效率更高,但是需要自己維護(hù)一個(gè)引用計(jì)數(shù)器。
shared_ptr比普通指針提供了更完善的功能。有一個(gè)小小的代價(jià),那就是一個(gè)共享指針比普通指針占用更多的空間,每一個(gè)對象都有一個(gè)共享指針,這個(gè)指針有引用計(jì)數(shù)器以便于釋放。但對于大多數(shù)實(shí)際情況,這些都是可以忽略不計(jì)的。intrusive_ptr 提供了一個(gè)折中的解決方案。它提供了一個(gè)輕量級的引用計(jì)數(shù)器,但必須對象本身已經(jīng)有了一個(gè)對象引用計(jì)數(shù)器。這并不是壞的想法,當(dāng)你自己的設(shè)計(jì)的類中實(shí)現(xiàn)智能指針相同的工作,那么一定已經(jīng)定義了一個(gè)引用計(jì)數(shù)器,這樣只需要更少的內(nèi)存,而且可以提高執(zhí)行性能。如果你要使用intrusive_ptr 指向類型T,那么你就需要定義兩個(gè)函數(shù):intrusive_ptr_add_ref 和intrusive_ptr_release。下面是一個(gè)簡單的例子解釋如何在自己的類中實(shí)現(xiàn):
#include "boost/intrusive_ptr.hpp"// forward declarations class CRefCounted; namespace boost {void intrusive_ptr_add_ref(CRefCounted * p);void intrusive_ptr_release(CRefCounted * p); };// My Class class CRefCounted {private:long references;friend void ::boost::intrusive_ptr_add_ref(CRefCounted * p);friend void ::boost::intrusive_ptr_release(CRefCounted * p);public:CRefCounted() : references(0) {} // initialize references to 0 }; // class specific addref/release implementation // the two function overloads must be in the boost namespace on most compilers: namespace boost {inline void intrusive_ptr_add_ref(CRefCounted * p){// increment reference count of object *p++(p->references);}inline void intrusive_ptr_release(CRefCounted * p){// decrement reference count, and delete object when reference count reaches 0if (--(p->references) == 0)delete p;} } // namespace boost
?這是一個(gè)最簡單的(非線程安全)實(shí)現(xiàn)操作。但作為一種通用的操作,如果提供一種基類來完成這種操作或許很有使用價(jià)值,也許在其他地方會介紹到。????????
5. Boost::weak_ptr<T>
????
強(qiáng)引用和弱引用的比較:
一個(gè)強(qiáng)引用當(dāng)被引用的對象活著的話,這個(gè)引用也存在(就是說,當(dāng)至少有一個(gè)強(qiáng)引用,那么這個(gè)對象就不能被釋放)。boost::share_ptr就是強(qiáng)引用。相對而言,弱引用當(dāng)引用的對象活著的時(shí)候不一定存在。僅僅是當(dāng)它存在的時(shí)候的一個(gè)引用。
boost::weak_ptr<T> 是執(zhí)行弱引用的智能指針。當(dāng)你需要它的時(shí)候就可以使用一個(gè)強(qiáng)(共享)指針指向它(當(dāng)對象被釋放的時(shí)候,它為空),當(dāng)然這個(gè)強(qiáng)指針在使用完畢應(yīng)該立即釋放掉,在上面的例子中我們能夠修改它為弱指針。
struct CBetterChild : public CSample {weak_ptr<CDad> myDad;void BringBeer(){shared_ptr<CDad> strongDad = myDad.lock(); // request a strong pointerif (strongDad) // is the object still alive?strongDad->SetBeer();// strongDad is released when it goes out of scope.// the object retains the weak pointer} };
? ? weak_ptr 就是一個(gè)弱指針。weak_ptr 被shared_ptr控制, 它可以通過share_ptr的構(gòu)造函數(shù)或者lock成員函數(shù)轉(zhuǎn)化為share_ptr。
??? weak_ptr的一個(gè)最大特點(diǎn)就是它共享一個(gè)share_ptr的內(nèi)存,但是無論是構(gòu)造還是析構(gòu)一個(gè)weak_ptr 都不會影響引用計(jì)數(shù)器。
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 boost::shared_ptr<test> sharePtr(new test);;
4 boost::weak_ptr<test> weakPtr(sharePtr);
5 //weakPtr 就是用來保存指向這塊內(nèi)存區(qū)域的指針的
6 //干了一大堆其他事情
7 boost::shared_ptr<test> sharePtr_2 = weakPtr.lock();
8 if (sharePtr_2)
9 sharePtr_2->print();
10 return 0;
11 }
6. Boost::shared_array<T> 和Boost::scoped_array<T>
??? 前面提到過shared_ptr和scoped_ptr不能用于數(shù)組的內(nèi)存(new []),所以shared_array和scoped_array就是他們的代替品。我們可以看下shared_array的用法
1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 const int size = 10;
4 boost::shared_array<test> a(new test[]);
5 for (int i = 0; i < size; ++i)
6 a[i].print();
7 return 0;
8 }
7. 使用智能指針的幾個(gè)注意點(diǎn)
??? 下面是幾個(gè)使用智能指針需要注意的地方:
??????????????? a: 聲明的時(shí)候要…_ptr<T> 而不是….._ptr<T*>
??????????????? b:不能把T* 型的指針賦值給它
??????????????? c: 不能寫ptr=NULl, 而用ptr.reset()代替。
8. 總結(jié)
??? 智能指針使用上還是比較簡單的, 而且能比較有效得解決C++內(nèi)存泄露的問題,各位使用C++的童鞋趕快用起來吧。
總結(jié)
以上是生活随笔為你收集整理的【Boost】boost库中智能指针概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Shell文件包含
- 下一篇: 【Boost】boost库中智能指针——