shared_ptr是新的標(biāo)準(zhǔn)庫的一個(gè)主要成員,作為一個(gè)非嵌入式的智能指針,其設(shè)計(jì)可謂已經(jīng)是絞盡腦汁。當(dāng)然,還有很多人對(duì)它提出了不滿。沒有完美的設(shè)計(jì),只有合適的設(shè)計(jì)。
1. shared_ptr最大的特點(diǎn)是接口的簡單性與實(shí)現(xiàn)的靈活性。
對(duì)于shared_ptr<Object>,object的內(nèi)存管理是可定制的,甚至可以定制引用計(jì)數(shù)結(jié)點(diǎn)的內(nèi)存分配,以滿足對(duì)內(nèi)存有特殊要求的情況。而這一切,都被Object的實(shí)現(xiàn)者隱藏起來,使用Object的客戶類是不用關(guān)心的。這和以前標(biāo)準(zhǔn)庫的組件實(shí)現(xiàn)策略有些不同。比如說, vector<int, A1>和vector<int, A2>,由于內(nèi)存分配策略的不同,而變成類型的不同,造成接口的改變。這一點(diǎn)在shared_ptr的設(shè)計(jì)時(shí)被避免了,當(dāng)然以一定的性能代價(jià)。shared_ptr作為C++面向?qū)ο笤O(shè)計(jì)的一個(gè)重要組件,接口的簡單性是很重要的,必須要有接口和實(shí)現(xiàn)的分離。與此相似的還有tr1::function的設(shè)計(jì)。
2.在同一體系中,各種類型的智能指針可以互相轉(zhuǎn)換。
如下例:
struct Object : InterfaceA, InterfaceB {
MemberA memberA;
};
shared_ptr<Object> obj(new Object);
shared_ptr<InterfaceA> a = obj;
shared_ptr<InterfaceB> b = obj;
shared_ptr<Object> p = static_pointer_cast<Object>(b);
shared_ptr<void> p2 = obj;
甚至還可以取得數(shù)據(jù)成員的智能指針:
shared_ptr<Object> obj(new Object);
shared_ptr<MemberA> memberA(obj, &obj->memberA);
再來說說shared_ptr的缺點(diǎn)。
1.對(duì)于使用引用計(jì)數(shù)的智能指針來說,必須要小心出現(xiàn)循環(huán)引用。
在重度使用shared_ptr的系統(tǒng)中,你必須一開始就明確類與類的關(guān)系,以決定哪里使用shared_ptr,哪里使用weak_ptr,否則就會(huì)出現(xiàn)內(nèi)存泄露。而
shared_ptr的接口轉(zhuǎn)換的靈活性,也很容易導(dǎo)致智能指針被濫用。內(nèi)存自動(dòng)管理的問題并沒有得到解決,它只是被轉(zhuǎn)移了。
2.shared_ptr使用非嵌入式設(shè)計(jì),這樣可以使用于基本類型,比如 shared_ptr<int>。但是根據(jù)個(gè)人經(jīng)驗(yàn),這種情況在很少使用。大部分情況還是使用自己設(shè)計(jì)的類。這有一個(gè)問題,就是沒有很方便的辦法實(shí)現(xiàn)this指針和智能指針的轉(zhuǎn)換。標(biāo)準(zhǔn)庫中提供了enable_shared_from_this類來解決這個(gè)問題。但這已經(jīng)使所謂的
非嵌入式設(shè)計(jì)徒有虛名。而假如一開始采用
嵌入式設(shè)計(jì)的話,則在性能代價(jià)和多線程設(shè)計(jì)方面具有更大的靈活性。