當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]正文?????????智能指針能夠使C++的開(kāi)發(fā)簡(jiǎn)單化,主要是它能夠像其它限制性語(yǔ)言(如C#、VB)自動(dòng)管理內(nèi)存的釋放,而且能夠做更多的事情。1、?什么是智能指針智能指針是一種像指針的C++對(duì)象,但它

正文

?????????智能指針能夠使C++的開(kāi)發(fā)簡(jiǎn)單化,主要是它能夠像其它限制性語(yǔ)言(如C#、VB)自動(dòng)管理內(nèi)存的釋放,而且能夠做更多的事情。


1、?什么是智能指針

智能指針是一種像指針的C++對(duì)象,但它能夠在對(duì)象不使用的時(shí)候自己銷(xiāo)毀掉。

我們知道在C++中的對(duì)象不再使用是很難定義的,因此C++中的資源管理是很復(fù)雜的。各種智能指針能夠操作不同的情況。當(dāng)然,智能指針能夠在任務(wù)結(jié)束的時(shí)候刪除對(duì)象,除了在程序之外。

許多庫(kù)都提供了智能指針的操作,但都有自己的優(yōu)點(diǎn)和缺點(diǎn)。Boost庫(kù)是一個(gè)高質(zhì)量的開(kāi)源的C++模板庫(kù),很多人都考慮將其加入下一個(gè)C++標(biāo)準(zhǔn)庫(kù)的版本中。


Boost提供了下面幾種智能指針:

shared_ptr

本指針中有一個(gè)引用指針記數(shù)器,表示類(lèi)型T的對(duì)象是否已經(jīng)不再使用。shared_ptr?是Boost中提供普通的智能指針,大多數(shù)地方都使用shared_ptr。

scoped_ptr

當(dāng)離開(kāi)作用域能夠自動(dòng)釋放的指針。因?yàn)樗遣粋鬟f所有權(quán)的。事實(shí)上它明確禁止任何想要這樣做的企圖!這在你需要確保指針任何時(shí)候只有一個(gè)擁有者時(shí)的任何一種情境下都是非常重要的。

intrusive_ptr

比?shared_ptr?更好的智能指針,但是需要類(lèi)型?T?提供自己的指針使用引用記數(shù)機(jī)制。

weak_ptr

一個(gè)弱指針,幫助shared_ptr?避免循環(huán)引用。

shared_array

和?shared_ptr?類(lèi)似,用來(lái)處理數(shù)組的。

scoped_array

和?scoped_ptr?類(lèi)似,用類(lèi)處理數(shù)組的。

?


下面讓我們看一個(gè)簡(jiǎn)單的例子:


2、?首先介紹:boost::scoped_ptr

scoped_ptr?是?Boost?提供的一個(gè)簡(jiǎn)單的智能指針,它能夠保證在離開(kāi)作用域后對(duì)象被釋放。

例子說(shuō)明:本例子使用了一個(gè)幫助我們理解的類(lèi):?CSample,?在類(lèi)的構(gòu)造函數(shù)、賦值函數(shù)、析構(gòu)函數(shù)中都加入了打印調(diào)試語(yǔ)句。因此在程序執(zhí)行的每一步都會(huì)打印調(diào)試信息。在例子的目錄里已經(jīng)包含了程序中需要的Boost庫(kù)的部分內(nèi)容,不需要下載其它內(nèi)容(查看Boost的安裝指南)。

下面的例子就是使用scoped_ptr?指針來(lái)自動(dòng)釋放對(duì)象的:

使用普通指針

使用scoped_ptr?指針

void?Sample1_Plain()

{

??CSample * pSample(new?CSample);

??if?(!pSample->Query() )

??// just some function...

??{

????delete?pSample;

????return;

??}

??pSample->Use();

??delete?pSample;

}

#include?"boost/smart_ptr.h"

void?Sample1_ScopedPtr()

{

??boost::scoped_ptr

???????samplePtr(new?CSample);

??if (!samplePtr->Query() )

??// just some function...

????return;???

??samplePtr->Use();

}

?

使用普通普通指針的時(shí)候,我們必須記住在函數(shù)退出的時(shí)候要釋放在這個(gè)函數(shù)內(nèi)創(chuàng)建的對(duì)象。當(dāng)我們使用例外的時(shí)候處理指針是特別煩人的事情(容易忘記銷(xiāo)毀它)。使用scoped_ptr?指針就能夠在函數(shù)結(jié)束的時(shí)候自動(dòng)銷(xiāo)毀它,但對(duì)于函數(shù)外創(chuàng)建的指針就無(wú)能為力了。

優(yōu)點(diǎn):對(duì)于在復(fù)雜的函數(shù)種,使用scoped_ptr?指針能夠幫助我們處理那些容易忘記釋放的對(duì)象。也因此在調(diào)試模式下如果使用了空指針,就會(huì)出現(xiàn)一個(gè)斷言。

優(yōu)點(diǎn)

自動(dòng)釋放本地對(duì)象和成員變量[1],延遲實(shí)例化,操作PIMPL和RAII(看下面)

缺點(diǎn)

在STL容器里,多個(gè)指針操作一個(gè)對(duì)象的時(shí)候需要注意。

性能

使用scoped_ptr?指針,會(huì)增加一個(gè)普通指針。

?


3、?引用指針計(jì)數(shù)器

引用指針計(jì)數(shù)器記錄有多少個(gè)引用指針指向同一個(gè)對(duì)象,如果最后一個(gè)引用指針被銷(xiāo)毀的時(shí)候,那么就銷(xiāo)毀對(duì)象本身。

shared_ptr?就是Boost中普通的引用指針計(jì)數(shù)器,它表示可以有多個(gè)指針指向同一個(gè)對(duì)象,看下面的例子:

void?Sample2_Shared()

{

??// (A)?創(chuàng)建Csample類(lèi)的一個(gè)實(shí)例和一個(gè)引用。

??boost::shared_ptr

??printf("The Sample now has %i referencesn", mySample.use_count());?// The Sample now has 1 references

??// (B)?付第二個(gè)指針給它。

??boost::shared_ptr

??printf("The Sample now has %i referencesn", mySample.use_count());

??// (C)?設(shè)置第一個(gè)指針為空。

??mySample.reset();

??printf("The Sample now has %i referencesn", mySample2.use_count());??//?一個(gè)引用

??//?當(dāng)mySample2離開(kāi)作用域的時(shí)候,對(duì)象只有一個(gè)引用的時(shí)候自動(dòng)被刪除。

}

?


在(A)中在堆棧重創(chuàng)建了CSample類(lèi)的一個(gè)實(shí)例,并且分配了一個(gè)shared_ptr指針。對(duì)象mySample入下圖所示:

然后我們分配了第二個(gè)指針mySample2,現(xiàn)在有兩個(gè)指針訪問(wèn)同一個(gè)數(shù)據(jù)。

我們重置第一個(gè)指針(將mySample設(shè)置為空),程序中仍然有一個(gè)Csample實(shí)例,mySample2有一個(gè)引用指針。

只要當(dāng)最有一個(gè)引用指針mySample2退出了它的作用域之外,Csample這個(gè)實(shí)例才被銷(xiāo)毀。

當(dāng)然,并不僅限于單個(gè)Csample這個(gè)實(shí)例,或者是兩個(gè)指針,一個(gè)函數(shù),下面是用shared_ptr的實(shí)例:

·?????????用作容器中。

·?????????用在PIMPL的慣用手法 (the pointer-to-implementation idiom?)。

·?????????RAII(Resource-Acquisition-Is-Initialization)的慣用手法中。

·?????????執(zhí)行分割接口。

注意:如果你沒(méi)有聽(tīng)說(shuō)過(guò)PIMPL (a.k.a. handle/body)?和?RAII,可以找一個(gè)好的C++書(shū),在C++中處于重要的內(nèi)容,一般C++程序員都應(yīng)該知道(不過(guò)我就是第一次看到這個(gè)寫(xiě)法)。智能指針只是一中方便的他們的方法,本文中不討論他們的內(nèi)容。

PIMPL:如果必須包容一個(gè)可能拋異常的子對(duì)象,但仍然不想從你自己的構(gòu)造函數(shù)中拋出異常,考慮使用被叫做Handle Class或Pimpl的方法(“Pimpl”個(gè)雙關(guān)語(yǔ):pImpl或“pointer to implementation”)


4、?主要特點(diǎn)

boost::shared_ptr?有一些重要的特征必須建立在其它操作之上。

·?????????shared_ptr

當(dāng)聲明或定義一個(gè)shared_ptr

·?????????shared_ptr

在這里本質(zhì)上不需要制定T的類(lèi)型(如從一個(gè)基類(lèi)繼承下來(lái)的)

·?????????shared_ptr

如果你的類(lèi)中自己寫(xiě)了釋放方法,也可以使用。具體參照Boost文檔。

·?????????強(qiáng)制轉(zhuǎn)換

如果你定義了一個(gè)U*能夠強(qiáng)制轉(zhuǎn)換到T*(因?yàn)門(mén)是U的基類(lèi)),那么shared_ptr也能夠強(qiáng)制轉(zhuǎn)換到shared_ptr

·?????????shared_ptr?是線程安全的

(這種設(shè)計(jì)的選擇超過(guò)它的優(yōu)點(diǎn),在多線程情況下是非常必要的)

·?????????已經(jīng)作為一種慣例,用在很多平臺(tái)上,被證明和認(rèn)同的。

5、?例子:在容器中使用shared_ptr

許多容器類(lèi),包括STL,都需要拷貝操作(例如,我們插入一個(gè)存在的元素到list,vector,或者container。)當(dāng)拷貝操作是非常銷(xiāo)毀資源的時(shí)候(這些操作時(shí)必須的),典型的操作就是使用容器指針。

std::vector

vec.push_back( new CMyLargeClass("bigString") );

?

將內(nèi)存管理的任務(wù)拋給調(diào)用者,我們能夠使用shared_ptr來(lái)實(shí)現(xiàn)。

typedef boost::shared_ptr

std::vector

vec.push_back( CMyLargeClassPtr(new CMyLargeClass("bigString")) );

?

當(dāng)vector被銷(xiāo)毀的時(shí)候,這個(gè)元素自動(dòng)被銷(xiāo)毀了。當(dāng)然,除非有另一個(gè)智能指針引用了它,則還本能被銷(xiāo)毀。讓我們看Sample3中的使用:

void?Sample3_Container()

{

??typedef?boost::shared_ptr

??// (A) create a container of CSample pointers:

??std::vector

??// (B) add three elements

??vec.push_back(CSamplePtr(new?CSample));

??vec.push_back(CSamplePtr(new?CSample));

??vec.push_back(CSamplePtr(new?CSample));

??// (C) "keep" a pointer to the second:

??CSamplePtr anElement = vec[1];

??// (D) destroy the vector:

??vec.clear();

??// (E) the second element still exists

??anElement->Use();

??printf("done. cleanup is automaticn");

??// (F) anElement goes out of scope, deleting the last CSample instance

}

?


6、?使用Boost中的智能指針,什么是正確的使用方法

使用智能指針的一些操作會(huì)產(chǎn)生錯(cuò)誤(突出的事那些不可用的引用計(jì)數(shù)器,一些對(duì)象太容易釋放,或者根本釋放不掉)。Boost增強(qiáng)了這種安全性,處理了所有潛在存在的危險(xiǎn),所以我們要遵循以下幾條規(guī)則使我們的代碼更加安全。

下面幾條規(guī)則是你應(yīng)該必須遵守的:

規(guī)則一:賦值和保存?——?對(duì)于智能指針來(lái)說(shuō),賦值是立即創(chuàng)建一個(gè)實(shí)例,并且保存在那里?,F(xiàn)在智能指針擁有一個(gè)對(duì)象,你不能手動(dòng)釋放它,或者取走它,這將幫助你避免意外地釋放了一個(gè)對(duì)象,但你還在引用它,或者結(jié)束一個(gè)不可用的引用計(jì)數(shù)器。

規(guī)則二:_ptr

·?????????當(dāng)創(chuàng)建一個(gè)智能指針的時(shí)候需要明確寫(xiě)出?__ptr

·?????????不能將T*賦值給一個(gè)智能指針。

·?????????不能寫(xiě)ptr = NULL,應(yīng)該使用ptr.reset()。

·?????????重新找回原始指針,使用ptr.get(),不必釋放這個(gè)指針,智能指針會(huì)去釋放、重置、賦值。使用get()僅僅通過(guò)函數(shù)指針來(lái)獲取原始指針。

·?????????不能通過(guò)T*指向函數(shù)指針來(lái)代表一個(gè)__ptr

·?????????這是一種特殊的方法來(lái)認(rèn)定這個(gè)智能指針擁有的原始指針。不過(guò)在Boost:smart pointer programming techniques?舉例說(shuō)明了許多通用的情況。

規(guī)則三:非循環(huán)引用?——?如果有兩個(gè)對(duì)象引用,而他們彼此都通過(guò)一個(gè)一個(gè)引用指針計(jì)數(shù)器,那么它們不能釋放,Boost?提供了weak_ptr來(lái)打破這種循環(huán)引用(下面介紹)。

規(guī)則四:非臨時(shí)的?share_ptr?——?不能夠造一個(gè)臨時(shí)的share_ptr來(lái)指向它們的函數(shù),應(yīng)該命名一個(gè)局部變量來(lái)實(shí)現(xiàn)。(這可以使處理以外更安全,Boost share_ptr best practices?有詳細(xì)解說(shuō))。

7、?循環(huán)引用

引用計(jì)數(shù)器是一種便利的資源管理機(jī)制,它有一個(gè)基本回收機(jī)制。但循環(huán)引用不能夠自動(dòng)回收,計(jì)算機(jī)很難檢測(cè)到。一個(gè)最簡(jiǎn)單的例子,如下:

struct?CDad;

struct?CChild;

typedef?boost::shared_ptr

typedef?boost::shared_ptr

struct?CDad : public CSample

{

???CChildPtr myBoy;

};

struct?CChild : public CSample

{

?CDadPtr myDad;

};

// a "thing" that holds a smart pointer to another "thing":

CDadPtr???parent(new?CDadPtr);

CChildPtr child(new?CChildPtr);

// deliberately create a circular reference:

parent->myBoy = child;

child->myDad = dad;

// resetting one ptr...

child.reset();

?

?????????parent?仍然引用CDad對(duì)象,它自己本身又引用CChild。整個(gè)情況如下圖所示:

如果我們調(diào)用dad.reset(),那么我們兩個(gè)對(duì)象都會(huì)失去聯(lián)系。但這種正確的離開(kāi)這個(gè)引用,共享的指針看上去沒(méi)有理由去釋放那兩個(gè)對(duì)象,我們不能夠再訪問(wèn)那兩個(gè)對(duì)象,但那兩個(gè)對(duì)象的確還存在,這是一種非常嚴(yán)重的內(nèi)存泄露。如果擁有更多的這種對(duì)象,那么將由更多的臨界資源不能正常釋放。

???????如果不能解決好共享智能指針的這種操作,這將是一個(gè)嚴(yán)重的問(wèn)題(至少是我們不可接受的)。因此我們需要打破這種循環(huán)引用,下面有三種方法:

A、???當(dāng)只剩下最后一個(gè)引用的時(shí)候需要手動(dòng)打破循環(huán)引用釋放對(duì)象。

B、???當(dāng)Dad的生存期超過(guò)Child的生存期的時(shí)候,Child需要一個(gè)普通指針指向Dad。

C、??使用boost::weak_ptr打破這種循環(huán)引用。

方法A和B并不是一個(gè)完美的解決方案,但是可以在不使用weak_ptr的情況下讓我們使用智能指針,讓我們看看weak_ptr的詳細(xì)情況。


8、?使用weak_ptr跳出循環(huán)

強(qiáng)引用和弱引用的比較:

一個(gè)強(qiáng)引用當(dāng)被引用的對(duì)象活著的話(huà),這個(gè)引用也存在(就是說(shuō),當(dāng)至少有一個(gè)強(qiáng)引用,那么這個(gè)對(duì)象就不能被釋放)。boost::share_ptr就是強(qiáng)引用。相對(duì)而言,弱引用當(dāng)引用的對(duì)象活著的時(shí)候不一定存在。僅僅是當(dāng)它存在的時(shí)候的一個(gè)引用。

boost::weak_ptr

struct CBetterChild : public CSample

{

??weak_ptr

??void BringBeer()

??{

????shared_ptr

????if (strongDad)??????????????????????// is the object still alive?

??????strongDad->SetBeer();

????// strongDad is released when it goes out of scope.

????// the object retains the weak pointer

??}

};

?

9、?Intrusive_ptr——輕量級(jí)共享智能指針

shared_ptr比普通指針提供了更完善的功能。有一個(gè)小小的代價(jià),那就是一個(gè)共享指針比普通指針占用更多的空間,每一個(gè)對(duì)象都有一個(gè)共享指針,這個(gè)指針有引用計(jì)數(shù)器以便于釋放。但對(duì)于大多數(shù)實(shí)際情況,這些都是可以忽略不計(jì)的。

intrusive_ptr?提供了一個(gè)折中的解決方案。它提供了一個(gè)輕量級(jí)的引用計(jì)數(shù)器,但必須對(duì)象本身已經(jīng)有了一個(gè)對(duì)象引用計(jì)數(shù)器。這并不是壞的想法,當(dāng)你自己的設(shè)計(jì)的類(lèi)中實(shí)現(xiàn)智能指針相同的工作,那么一定已經(jīng)定義了一個(gè)引用計(jì)數(shù)器,這樣只需要更少的內(nèi)存,而且可以提高執(zhí)行性能。

如果你要使用intrusive_ptr?指向類(lèi)型T,那么你就需要定義兩個(gè)函數(shù):intrusive_ptr_add_ref?和intrusive_ptr_release。下面是一個(gè)簡(jiǎn)單的例子解釋如何在自己的類(lèi)中實(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 0

???if (--(p->references) == 0)

?????delete p;

??}

} // namespace boost

?

????????

?????????這是一個(gè)最簡(jiǎn)單的(非線程安全)實(shí)現(xiàn)操作。但作為一種通用的操作,如果提供一種基類(lèi)來(lái)完成這種操作或許很有使用價(jià)值,也許在其他地方會(huì)介紹到。


10、?scoped_array?和?shared_array

scoped_array?和?shared_array和上面講的基本上相同,只不過(guò)他們是指向數(shù)組的。就像使用指針操作一樣使用operator new[]?,他們都重載了operator new[]。注意他們并不初始化分配長(zhǎng)度。

11、?Boost的安裝

從www.boost.org上下載最新版本的boost,然后解壓縮到你指定的目錄里,解壓縮后的文件目錄如下:

Boost?????boost的源文件和頭文件。

Doc????????HTML格式的文檔。

Lib?????????庫(kù)文件(不是必需的)

…?????????????其他文件(“more”里有其他資料)

添加目錄到我們自己的IDE里:

VC6:在菜單Tools/Options,Directories tab, "Show Directories for... Include files",

VC7:?在菜單Tools/Options,??Projects/VC++ directories, "Show Directories for... Include files".

Boost的頭文件都在boost子目錄里,例如本文檔例子中有#include "boost/smart_ptr.hpp"。所以任何人當(dāng)讀到年的源文件的時(shí)候就立刻知道你用到了boost中的智能指針。

12、?關(guān)于本文檔中的例子

本文檔中的例子里有一個(gè)子目錄boost僅僅包含了本例子中使用到的一些頭文件,僅僅是為了你編譯這個(gè)例子,如果你需要下載完整的boost或者獲取更多的資源請(qǐng)到www.boost.org。

13、?VC6中min/max的災(zāi)難


當(dāng)在VC中使用boost庫(kù),或者其他庫(kù)的時(shí)候會(huì)有一些小的問(wèn)題。

在Windows的頭文件中已經(jīng)定義了min?和?max宏,所以在STL中的這兩個(gè)函數(shù)就調(diào)用不到了,例如在MFC中就是這樣,但是在Boost中,都是使用的std::命名空間下的函數(shù),使用Windows的函數(shù)不能夠接受不同類(lèi)型的參數(shù)在模板中使用,但是許多庫(kù)都依賴(lài)這些。

雖然Boost盡量處理這些問(wèn)題,但有時(shí)候遇到這樣的問(wèn)題的時(shí)候就需要在自己的代碼中加入像下面的代碼在第一個(gè)#include前加入#define _NOMINMAX。

#define _NOMINMAX????????????// disable windows.h defining min and max as macros

#include "boost/config.hpp"??// include boosts compiler-specific "fixes"

using std::min;??????????????// makle them globally available

using std::max;

?

?????????這樣操作并不是在任何時(shí)候都需要,而只有我們碰到使用了就需要加入這段代碼。


14、?資源

獲取更多的信息,或者有問(wèn)題可以查找如下資源:

·?????????Boost home page

·?????????Download Boost

·?????????Smart pointer overview

·?????????Boost users mailing list

·?????????Boost中的智能指針(撰文??Bjorn Karlsson????翻譯??曾毅)


在你的代碼中使用Boost智能指針

Smart Pointers to boost your code(By peterchen)?

翻譯?masterlee

?

Download source files - 45.3kb

?

正文

?????????智能指針能夠使C++的開(kāi)發(fā)簡(jiǎn)單化,主要是它能夠像其它限制性語(yǔ)言(如C#、VB)自動(dòng)管理內(nèi)存的釋放,而且能夠做更多的事情。

?

?

1、?什么是智能指針

智能指針是一種像指針的C++對(duì)象,但它能夠在對(duì)象不使用的時(shí)候自己銷(xiāo)毀掉。

我們知道在C++中的對(duì)象不再使用是很難定義的,因此C++中的資源管理是很復(fù)雜的。各種智能指針能夠操作不同的情況。當(dāng)然,智能指針能夠在任務(wù)結(jié)束的時(shí)候刪除對(duì)象,除了在程序之外。

許多庫(kù)都提供了智能指針的操作,但都有自己的優(yōu)點(diǎn)和缺點(diǎn)。Boost庫(kù)是一個(gè)高質(zhì)量的開(kāi)源的C++模板庫(kù),很多人都考慮將其加入下一個(gè)C++標(biāo)準(zhǔn)庫(kù)的版本中。

?

Boost提供了下面幾種智能指針:

?

shared_ptr

本指針中有一個(gè)引用指針記數(shù)器,表示類(lèi)型T的對(duì)象是否已經(jīng)不再使用。shared_ptr?是Boost中提供普通的智能指針,大多數(shù)地方都使用shared_ptr。

scoped_ptr

當(dāng)離開(kāi)作用域能夠自動(dòng)釋放的指針。因?yàn)樗遣粋鬟f所有權(quán)的。事實(shí)上它明確禁止任何想要這樣做的企圖!這在你需要確保指針任何時(shí)候只有一個(gè)擁有者時(shí)的任何一種情境下都是非常重要的。

intrusive_ptr

比?shared_ptr?更好的智能指針,但是需要類(lèi)型?T?提供自己的指針使用引用記數(shù)機(jī)制。

weak_ptr

一個(gè)弱指針,幫助shared_ptr?避免循環(huán)引用。

shared_array

和?shared_ptr?類(lèi)似,用來(lái)處理數(shù)組的。

scoped_array

和?scoped_ptr?類(lèi)似,用類(lèi)處理數(shù)組的。

?

?

下面讓我們看一個(gè)簡(jiǎn)單的例子:

?

2、?首先介紹:boost::scoped_ptr

scoped_ptr?是?Boost?提供的一個(gè)簡(jiǎn)單的智能指針,它能夠保證在離開(kāi)作用域后對(duì)象被釋放。

例子說(shuō)明:本例子使用了一個(gè)幫助我們理解的類(lèi):?CSample,?在類(lèi)的構(gòu)造函數(shù)、賦值函數(shù)、析構(gòu)函數(shù)中都加入了打印調(diào)試語(yǔ)句。因此在程序執(zhí)行的 每一步都會(huì)打印調(diào)試信息。在例子的目錄里已經(jīng)包含了程序中需要的Boost庫(kù)的部分內(nèi)容,不需要下載其它內(nèi)容(查看Boost的安裝指南)。

?

下面的例子就是使用scoped_ptr?指針來(lái)自動(dòng)釋放對(duì)象的:

?

使用普通指針

使用scoped_ptr?指針

void?Sample1_Plain()

{

??CSample * pSample(new?CSample);

?

??if?(!pSample->Query() )

??// just some function...

??{

????delete?pSample;

????return;

??}

?

??pSample->Use();

??delete?pSample;

}

#include?"boost/smart_ptr.h"

?

void?Sample1_ScopedPtr()

{

??boost::scoped_ptr

???????samplePtr(new?CSample);

?

??if (!samplePtr->Query() )

??// just some function...

????return;???

?

??samplePtr->Use();

?

}

?

使用普通普通指針的時(shí)候,我們必須記住在函數(shù)退出的時(shí)候要釋放在這個(gè)函數(shù)內(nèi)創(chuàng)建的對(duì)象。當(dāng)我們使用例外的時(shí)候處理指針是特別煩人的事情(容易忘記銷(xiāo)毀它)。使用scoped_ptr?指針就能夠在函數(shù)結(jié)束的時(shí)候自動(dòng)銷(xiāo)毀它,但對(duì)于函數(shù)外創(chuàng)建的指針就無(wú)能為力了。

優(yōu)點(diǎn):對(duì)于在復(fù)雜的函數(shù)種,使用scoped_ptr?指針能夠幫助我們處理那些容易忘記釋放的對(duì)象。也因此在調(diào)試模式下如果使用了空指針,就會(huì)出現(xiàn)一個(gè)斷言。

?

?

優(yōu)點(diǎn)

自動(dòng)釋放本地對(duì)象和成員變量[1],延遲實(shí)例化,操作PIMPL和RAII(看下面)

缺點(diǎn)

在STL容器里,多個(gè)指針操作一個(gè)對(duì)象的時(shí)候需要注意。

性能

使用scoped_ptr?指針,會(huì)增加一個(gè)普通指針。

?

?

3、?引用指針計(jì)數(shù)器?

引用指針計(jì)數(shù)器記錄有多少個(gè)引用指針指向同一個(gè)對(duì)象,如果最后一個(gè)引用指針被銷(xiāo)毀的時(shí)候,那么就銷(xiāo)毀對(duì)象本身。

shared_ptr?就是Boost中普通的引用指針計(jì)數(shù)器,它表示可以有多個(gè)指針指向同一個(gè)對(duì)象,看下面的例子:

?

void?Sample2_Shared()

{

??// (A)?創(chuàng)建Csample類(lèi)的一個(gè)實(shí)例和一個(gè)引用。

??boost::shared_ptr

??printf("The Sample now has %i referencesn", mySample.use_count());?// The Sample now has 1 references

??// (B)?付第二個(gè)指針給它。

??boost::shared_ptr

??printf("The Sample now has %i referencesn", mySample.use_count());

?

??// (C)?設(shè)置第一個(gè)指針為空。

??mySample.reset();

??printf("The Sample now has %i referencesn", mySample2.use_count());??//?一個(gè)引用

?

??//?當(dāng)mySample2離開(kāi)作用域的時(shí)候,對(duì)象只有一個(gè)引用的時(shí)候自動(dòng)被刪除。

}

?

?

在(A)中在堆棧重創(chuàng)建了CSample類(lèi)的一個(gè)實(shí)例,并且分配了一個(gè)shared_ptr指針。對(duì)象mySample入下圖所示:

?

?

?

然后我們分配了第二個(gè)指針mySample2,現(xiàn)在有兩個(gè)指針訪問(wèn)同一個(gè)數(shù)據(jù)。

?

?

?

我們重置第一個(gè)指針(將mySample設(shè)置為空),程序中仍然有一個(gè)Csample實(shí)例,mySample2有一個(gè)引用指針。

?

?

?

只要當(dāng)最有一個(gè)引用指針mySample2退出了它的作用域之外,Csample這個(gè)實(shí)例才被銷(xiāo)毀。

?

?

?

當(dāng)然,并不僅限于單個(gè)Csample這個(gè)實(shí)例,或者是兩個(gè)指針,一個(gè)函數(shù),下面是用shared_ptr的實(shí)例:

用作容器中。用在PIMPL的慣用手法 (the pointer-to-implementation idiom?)。RAII(Resource-Acquisition-Is-Initialization)的慣用手法中。執(zhí)行分割接口。

注意:如果你沒(méi)有聽(tīng)說(shuō)過(guò)PIMPL (a.k.a. handle/body)?和?RAII,可以找一個(gè)好的C++書(shū),在C++中處于重要的內(nèi)容,一般C++程序員都應(yīng)該知道(不過(guò)我就是第一次看到這個(gè)寫(xiě) 法)。智能指針只是一中方便的他們的方法,本文中不討論他們的內(nèi)容。

PIMPL:如果必須包容一個(gè)可能拋異常的子對(duì)象,但仍然不想從你自己的構(gòu)造函數(shù)中拋出異常,考慮使用被叫做Handle Class或Pimpl的方法(“Pimpl”個(gè)雙關(guān)語(yǔ):pImpl或“pointer to implementation”)

?

4、?主要特點(diǎn)?

boost::shared_ptr?有一些重要的特征必須建立在其它操作之上。

shared_ptr

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉