[筆記]2.智能指針

智能指針

原生指針是一款很強大的工具,但是依據進數十年的經驗,可以確定的一點是:稍有不慎,這 個工具就會反噬它的使用者。

C++11標準中規定了四個智能指針:
std::auto_ptr,std::unique_ptr,std::shared_ptr,std::weak_ptr.他們都是用來輔助管理動態分配對象的聲明週期。

std::unique_ptr

當要使用一個智能指針的時候,首先要想到的應該是std::unique_ptr。默認情況下,std::unique_ptr和原生指針同等大小,對於大多數操作,他們執行的底層指令也一樣。

std::unique_ptr具現了獨佔語義,一個非空的std::unique_ptr永遠擁有它指向的對象。

很容易將一個std::unique_ptr轉化爲std::shared_ptr.

    std::unique_ptr<Widget> getWidget();

    std::shared_ptr<Widget> pWidget = getWidget();

std::shared_ptr

std::shared_ptr通過引用計數來管理對象的生命週期。std::shared_ptr的構造函數自動遞增這個計數,析構函數自動遞減這個計數。如果std::shared_ptr在執行減一後發現引用計數變成了0,說明沒有其他的std::shared_ptr在指向這個資源了,所以std::shared_ptr直接析構了它指向的空間。

std::shared_ptr是std::unique_ptr的兩倍大,除了控制塊,還有需要原子引用計數操作引起的開銷

避免從原生指針類型變量創建std::shared_ptr,若無法避免,請使用new

auto pw = new Widget;

std::shared_ptr<Widget> spw1(pw);
std::shared_ptr<Widget> spw2(pw);            // 到此爲止,爲pw創建了兩個智能指針,且其計數都分別爲1,當進行釋放時,第一次析構沒有問題,第二次析構時pw已經不存在了,這就產生了一個未定義行爲

std::shared_ptr spw1(new Widget);      // 直接使用new
std::shared_ptr spw2(spw1);            // 這樣就沒有問題了

std::weak_ptr

std::weak_ptr不能被單獨使用,它是std::shared_ptr作爲參數的產物。std::weak_ptr通常有一個std::shared_ptr來創建,他們指向相同地址,std::shared_ptr來初始化他們,但是std::weak_ptr不會影響到它所指對象的引用計數。

auto spw = std::make_shared<Widget>();

std::weak_ptr<Widget> wpw(spw);

spw = nullptr;

if (wpw.expired())
{
	/* code */
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章