青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

std::tr1::shared_ptr 使用的一點體會

Posted on 2010-09-03 22:29 S.l.e!ep.¢% 閱讀(4089) 評論(0)  編輯 收藏 引用 所屬分類: C++

在 c++ 98 里面只有一種智能指針,就是 std::auto_ptr,因為具有唯一所有權的特征,所以限制了它的使用范圍,比如你無法在容器中使用它。而我們知道 stl 容器是值語義的,如果不能用智能指針管理的話,只有兩種辦法來使用。

一種是類似這樣:

std::vector<std::string> names;
names.push_back("cyberscorpio");
std::string name("news818");
names.push_back(name);

每次向容器中添加內容的時候,實際上產生了該內容的另一份拷貝,對于簡單的內容(或對象)來說,問題不大,但如果是很復雜的內容,很大的對象,調用拷貝構造函數的成本會比較高,同時亦不利于統一維護。

另一種做法就是在容器中存指針,這樣當然就避免了上面的問題,但是,這需要你在容器對象銷毀的時候,顯式的釋放容器中的每一個元素。略有些不方便,但還可以接受。

更大的問題在于,當程序比較復雜的時候,對象的生命周期管理對程序員來說,會是一個比較頭疼的事情,比如你有一個指針(對象),在程序的很多地方都用到它,如果你在某個地方釋放了它而沒有通知它的其他使用者的話,就會造成非法的內存訪問,從而程序崩潰。

shared_ptr 通過指針的引用計數,很好的解決了這個問題,和 COM 組件生存期管理機制類似,只有當引用計數為 0 的時候,才會釋放這個對象。而 shared_ptr 不需要程序員手工調用 AddRef 和 Release 函數,進一步減小了出錯的可能性。

但是,引用計數有一個麻煩,它不能解決所謂循環引用的問題,舉個例子,有對象 A 和 B,A 和 B 中,各有一個智能指針指向對方。

#include <stdio.h>
#include <memory>
class A;
class B;
typedef std::tr1::shared_ptr<a> APtr;
typedef std::tr1::shared_ptr<b> BPtr;

class A {
public:
BPtr b;
~A () {
printf ("A released\n");
}
};

class B {
public:
APtr a;
~B () {
printf ("B released\n");
}
};

int main () {
APtr a(new A());
BPtr b(new B());

a->b = b; // 1
b->a = a; // 2

return 0;

}

我們編譯運行這段程序,會發現 A 和 B 的析構函數都沒有被調用,因為在只能指針 a 的生命周期結束的時候,它手中對 A 對象的引用計數還剩下 1 (即 b 手中的引用),所以對象 A 不會被釋放。而指針 b 生命結束的時候哦,它手中 B 對象的引用也還有 1,導致沒有對象被釋放。

上面的例子里面,注釋為 1 和 2 的兩句,任意去掉一句,就打破了這個循環的引用,從而 A 和 B 都能正確的釋放。那么,假如我真的需要 A 和 B 之間互相引用,難道就沒有別的辦法了嗎?辦法是有的,就是使用 std::tr1::weak_ptr。weak_ptr,顧名思義,是一個 “弱” 一點的智能指針,它不會增加引用計數,當你需要使用這個對象的時候,可以從 weak_ptr 臨時生出一個 shared_ptr 來 (通過 lock 函數),這個臨時的 shared_ptr 生命結束以后,就會把引用計數減小 1,這樣就不會出現互相死鎖的情況了。

#include <stdio.h>
#include <memory>
class A;
class B;

typedef std::tr1::shared_ptr<A> APtr;
typedef std::tr1::shared_ptr<B> BPtr;
typedef std::tr1::weak_ptr<A> AWeakPtr;
typedef std::tr1::weak_ptr<B> BWeakPtr;

class A {
public:
BWeakPtr b; // 注意這里
~A () {
printf ("A released\n");
}

};

class B {
public:
AWeakPtr a; // 注意這里
~B () {
printf ("B released\n");
}

void output () {
printf ("I'm B\n");
}
};

int main () {
APtr a(new A());
BPtr b(new B());

a->b = b;
b->a = a;

BPtr b2(a->b.lock());
b2->output();

return 0;
}

編譯運行,我們會欣喜的看到,A 和 B 都正確的被釋放了。

I'm B
B released
A released

所以,在使用 shared_ptr 第一個要注意的,就是在可能會引起循環引用的地方,使用 weak_ptr

還有一個問題也很常見,當使用了 shared_ptr 的時候,我們可能需要在所有的地方都使用它,否則就不容易達到管理生存期的目的了。但有的時候,我們手頭上只有對象的原始指針,比如在對象的函數內部,我們只有 this。這就迫切的需要一個功能:如何從對象的裸指針中,生成我們需要的 shared_ptr。

有人可能會覺得這個簡單,shared_ptr<T> a(this); 不就行了么?很遺憾的告訴你,這樣不行,會出問題。為什么呢?因為這里的 a,手中對 this 的引用計數只有 1,它無法知道其他地方智能指針對 this 這個指針(就是這個對象)的引用情況,因此當 a 的生命周期結束(比如函數返回)的時候,this 就會被它毫不留情的釋放掉,其他地方的相關智能指針,手中拿著的該對象指針已經變成非法。

那么怎樣解決呢?也很簡單,使用 std::tr1::enable_shared_from_this 作為基類。比如:

class A : public std::tr1::enable_shared_from_this<A> 
{
public:
std::tr1::shared_ptr<A> getSharedPtr() {
return shared_from_this();
}
};

這樣就可以從 this 中生出具有統一引用計數的 shared_ptr 了。只有一個問題是需要注意的,就是 getSharedPtr 函數,或者說 shared_from_this 不能在對象 A 的構造函數中調用。因為 enable_shared_from_this 這個基類的內部,是通過一個對自己的 weak_ptr 的引用來返回 this 的 shared_ptr 的,而在對象的構造函數中,第一個 shared_ptr 尚未獲得對象的指針,所以 weak_ptr 是空的,直接導致 shared_from_this() 返回失敗。除此以外,shared_from_this 可以隨便使用。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲品质自拍| 国产精品视频一二三| 亚洲高清色综合| 久久激情五月激情| 羞羞答答国产精品www一本| 欧美一区二区三区男人的天堂| 亚洲视频电影图片偷拍一区| 一区二区三区四区五区在线 | 久久国产欧美精品| 欧美一区影院| 久久精品免费| 蜜臀a∨国产成人精品| 奶水喷射视频一区| 亚洲免费福利视频| 欧美激情一区二区三区四区| 欧美欧美全黄| 亚洲无线视频| 久久超碰97中文字幕| 麻豆精品在线视频| 免费av成人在线| 欧美四级电影网站| 国产精品美女主播在线观看纯欲| 欧美日韩在线免费| 欧美精品午夜| 欧美日韩一区二区三区免费看| 欧美视频网址| 国产精品一区视频| 亚洲肉体裸体xxxx137| 日韩一区二区电影网| 日韩香蕉视频| 久久一二三四| 亚洲天堂视频在线观看| 欧美亚州韩日在线看免费版国语版| 亚洲国产精品成人一区二区| 亚洲第一在线| 亚洲午夜视频在线| 久久国产精品电影| 亚洲国产成人精品视频 | 欧美成人一二三| 在线中文字幕不卡| 久久人91精品久久久久久不卡| 免费一级欧美在线大片| 久久久久久**毛片大全| 亚洲激情视频网| 久久综合一区| 国内精品美女在线观看| 午夜精品久久久久久久白皮肤 | 亚洲国产精品第一区二区| 亚洲一区三区在线观看| 亚洲高清不卡在线| 欧美在线高清视频| 国产精品美女久久久久久久 | 欧美日韩色婷婷| 亚洲欧洲日本mm| 免费人成精品欧美精品| 欧美一区二区三区婷婷月色| 国产精品电影网站| 亚洲综合久久久久| 一区二区免费看| 欧美日本一道本| 日韩一级在线观看| 亚洲国产一区二区三区a毛片| 久久av一区二区| 久久gogo国模啪啪人体图| 一区二区冒白浆视频| 亚洲狠狠婷婷| 欧美激情精品久久久久久| 亚洲理伦电影| 亚洲乱码国产乱码精品精天堂| 欧美电影在线免费观看网站| 亚洲黄色性网站| 最近中文字幕日韩精品 | 中国成人黄色视屏| 欧美亚洲不卡| 欧美在线视频免费播放| 午夜免费电影一区在线观看| 欧美日韩精品一区二区天天拍小说 | 这里只有视频精品| 国产精品国产a级| 亚洲欧美国内爽妇网| 亚洲一区三区视频在线观看| 国产精品久久久久一区二区三区| 亚洲欧美国产日韩天堂区| 香蕉久久夜色精品| 在线观看日韩精品| 欧美大片一区| 欧美日韩福利视频| 一本色道精品久久一区二区三区| 日韩午夜电影| 国产精品亚洲综合久久| 欧美一级久久久| 麻豆freexxxx性91精品| 日韩视频三区| 亚洲一区二区影院| 激情校园亚洲| 亚洲蜜桃精久久久久久久| 国产精品二区在线观看| 久久精品国产99精品国产亚洲性色| 久久久国产亚洲精品| 这里是久久伊人| 欧美在线不卡视频| 一区二区三区回区在观看免费视频| 一区二区三区**美女毛片| 国产日韩欧美综合| 亚洲国产精品久久久久久女王| 久久综合伊人77777蜜臀| 香蕉成人伊视频在线观看| 另类综合日韩欧美亚洲| 欧美激情小视频| 欧美一区二区福利在线| 欧美v国产在线一区二区三区| 日韩一级欧洲| 亚洲宅男天堂在线观看无病毒| 久久久精品国产免大香伊| 久久久久久久激情视频| 亚洲一区二区欧美| 美女国内精品自产拍在线播放| 性做久久久久久久免费看| 欧美—级在线免费片| 老鸭窝亚洲一区二区三区| 国产精品网红福利| 欧美激情第1页| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 久久精品视频亚洲| 午夜视频在线观看一区二区三区| 久久精品亚洲国产奇米99| 小黄鸭精品aⅴ导航网站入口| 欧美精品一区二区三区蜜臀| 欧美岛国在线观看| 狠狠色狠狠色综合系列| 亚欧成人在线| 亚欧成人精品| 国产精品麻豆欧美日韩ww| 一区二区三区日韩精品| 亚洲视频免费在线| 欧美日韩免费视频| 亚洲国产人成综合网站| 在线观看成人av| 久久精品国产999大香线蕉| 欧美亚洲尤物久久| 国产精品国产三级国产专播品爱网 | 欧美日韩免费观看一区三区| 亚洲黑丝在线| 一区二区欧美激情| 欧美理论片在线观看| 91久久久在线| 亚洲桃色在线一区| 欧美日韩国内自拍| 妖精成人www高清在线观看| 国产精品99久久久久久白浆小说| 欧美精品色网| 亚洲色图综合久久| 久久精精品视频| 伊人成年综合电影网| 久久午夜视频| 亚洲激情在线视频| 亚洲天堂视频在线观看| 国产精品福利av| 午夜精品亚洲| 老司机免费视频久久| 亚洲电影观看| 欧美日韩不卡合集视频| 亚洲小说春色综合另类电影| 久久精品亚洲| 亚洲国产视频直播| 欧美激情视频一区二区三区免费 | 欧美日韩岛国| 欧美一区二区三区久久精品茉莉花| 欧美激情无毛| 亚洲午夜精品福利| 国产欧美视频一区二区三区| 久久精品人人做人人综合| 欧美激情精品久久久久久黑人 | 国产视频亚洲精品| 蜜臀久久久99精品久久久久久 | 国产日韩精品一区二区浪潮av| 久久er精品视频| 91久久中文| 久久综合精品国产一区二区三区| 国产精品成人一区二区网站软件| 欧美一区二区免费观在线| 亚洲国产日韩欧美在线图片| 香蕉久久夜色精品国产使用方法| 亚洲国产另类久久精品| 国产欧美精品日韩区二区麻豆天美| 久久综合色天天久久综合图片| 亚洲一区二区欧美日韩| 亚洲国产另类 国产精品国产免费| 欧美一区二区三区精品电影| 亚洲精品裸体| 1204国产成人精品视频| 国产精品腿扒开做爽爽爽挤奶网站| 欧美v国产在线一区二区三区| 欧美与黑人午夜性猛交久久久| 在线一区二区三区四区| 亚洲国产精品视频| 欧美国产日韩精品| 免费观看一级特黄欧美大片| 欧美在线网站| 欧美一二三区在线观看|