文章目錄
-
- 對智能指針的思考
-
- shared_ptr
- enable_shared_from_this
- weak_ptr
- Unique_ptr
對智能指針的思考
shared_ptr
設計意圖是為了更友善,更安全的管理堆上配置設定的對象。
原理是利用了
raii
的特性在對象出作用域後會自動調用析構函數,進而在判定自己是最後一個持有管理對象的情況下,調用其析構函數,釋放記憶體。
特性 { 構造,copy構造,指派,移動構造,移動指派}
-
std::shared_ptr<int> a(new int(1)); //a:use 1 std::shared_ptr<int> b(a); //b:use 2 ; a:use 2 std::shared_ptr<int> c(std::move(b)); //c:use 2 ; a:use 2 ; b:empty
enable_shared_from_this
C11新特性
weak_ptr
設計意圖: 這裡我想從它的特性來反看為啥設計這個東西。
它的特性是: 不參與控制所指對象的生命周期, 在
shared_ptr
發現自己是最後一個管理對象的時候,在其析構的時候會直接釋放掉所管理的對象,即使這個時候還有
weak_ptr
指向這個對象,是以在用它的時候要先
lock()
一下看看傳回的是不是空的
shared_ptr
。
它與直接用裸指針的差別是 它可以檢測所指的對象是否被析構
是以這裡可以看出來是為了配合
weak_ptr
來控制所接管對象的,并且從它的源碼可以看出它不能直接接管所指對象,如下。
shared_ptr
weak_ptr<classType> type(new ClassType) //這樣不行
疑問 :如下
nn1 == nn3 == 8
編譯器配置設定了8個位元組 其中4個位元組的指針來指向接管的對象,另外4位元組指針指向一個控制塊,我的問題是這個控制塊裡為啥要分 強引用計數 和 弱引用計數 ,弱引用計數有啥用我感覺可以去掉!
//接上面的 win32 debug平台
std::weak_ptr<IBase> d(c);
int nn1 = sizeof(d);
int nn3 = sizeof(c);
場景 循環引用打破
class IBaseA
{
shared_ptr<IBaseB> m_iB;
};
class IBaseB
{
shared_ptr<IBaseA> m_iA;
}
{
std::shared_ptr<IBaseA> IA(new IBaseA);
std::shared_ptr<IBaseB> IB(new IBaseB)
IA->m_iB = IB;
IB->m_iA = IA;
assert(IA.use_count() == 2);
assert(IB.use_count() == 2);
}
//出作用域後 明明沒有shared_ptr指向 IBaseA 或 IBaseB, 但由于它們引用計數都是二是以即使出作用域也是改為1 造成記憶體洩漏。
參考連接配接 :SharedAnalyse
Unique_ptr
特性 與
shared_ptr
不同它沒有 copy構造函數與指派運算符。vs中源碼如下:
class unique_ptr
{ // non-copyable pointer to an object
public:
//....
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept;
unique_ptr& operator=(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept
{ // assign by moving _Right
reset(_Right.release());
this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter());
return (*this);
}
};
同一時刻隻能有一個
unique_ptr
接管所指的對象, 它與
auto_ptr
不同之處在與它可以放在容器中,這就是利用了它雖然不能copy但能移動構造的特點。
設計意圖 這方面我覺得它是為了用更小的代價來管理所接管對象,因為比之
shared_ptr
來說它不用維護一個引用計數器。