在c++中,動態記憶體管理是通過運算子new來開闢空間的,然後用delete來釋放這個空間。
動態記憶體很容易出現問題,因為確保在正確的時間釋放記憶體是很困難的。有時我們會忘記釋放記憶體,這樣就會造成記憶體洩露;有時在還有指標引用記憶體的時候就釋放了它,這時就會出現引用非法記憶體的指標。
舉個例子:
[cpp]
view plain
copy
void
test ()
//...
delete
p1;
}
如果在1f判斷中我們忘記delete p1 ,直接return,那麼這塊記憶體就沒有釋放,很容易造成記憶體洩露。
所以我們需要使用智慧型指標來管理動態物件。
所謂智慧型指標就是智慧型/自動化的管理指標所指向的動態資源的釋放。
stl--auto_ptr
boost庫的智慧型指標(ps:新的c++11標準中已經引入了
unique_ptr/shared_ptr/weak_ptr)
下面我們分別來看一下這幾個智慧型指標:
1)scoped_ptr:
這是比較簡單的一種智慧型指標,正如其名字所述,scoped_ptr所指向的物件在作用域之外會自動得到析構,
scoped_ptr是non-copyable的,也就是說你不能去嘗試複製乙個scoped_ptr的內容到另外乙個scoped_ptr中,這也是為了防止錯誤的多次析構同乙個指標所指向的物件。
顧名思義,守衛的指標,思想就是防拷貝,在大多時候用不到拷貝構造和賦值運算子過載,那麼我們做的就是寫出建構函式和析構函式,拷貝構造和賦值運算子過載只宣告不定義。
[cpp]
view plain
copy
template
<
class
t>
class
scopedptr
scopedptr()
:_ptr(null)
{}
~scopedptr()
} t& operator*()
t* getptr()
protected
: scopedptr(const
scopedptr& p);
scopedptr& operator = (const
scopedptr& p);
private
: t* _ptr;
};
void
test()
intmain()
2)shared_ptr
:shared_ptr是乙個最像指標的"智慧型指標".
shared_ptr與scoped_ptr一樣包裝了new操作符在堆上分配的動態物件,但它實現的是引用計數型的智慧型指標,可以被自由的拷貝和賦值,在任意的地方共享它,當沒有**使用(引用計數為0)它時才能刪除被包裝的動態分配的物件。shared_ptr也可以安全地放到標準容器中,並彌補了auto_ptr因為轉移語義而不能把指標做為stl容器元素的缺陷。
下面我們來實現以下這個智慧型指標。
[cpp]
view plain
copy
#pragma once
template
<
class
t>
class
sharedptr
sharedptr(t *ptr)
:_ptr(ptr)
, _pcount(new
int(1))
{}
sharedptr(const
sharedptr& sp)
:_ptr(sp._ptr)
, _pcount(sp._pcount)
~sharedptr()
_ptr = null;
} }
sharedptr& operator=(const
sharedptr&sp)
_ptr = sp._ptr;
_pcount = sp._pcount;
++(*_pcount);
} return
*this
; }
private
: t* _ptr;
int*_pcount;
};
void
test()
intmain()
2)auto
_ptr
:auto_ptr 是c++標準庫提供的類模板,auto_ptr物件通過初始化指向由new建立的動態記憶體,它是這塊記憶體的擁有者,一塊記憶體不能同時被分給兩個擁有者。當auto_ptr物件生命週期結束時,其析構函式會將auto_ptr物件擁有的動態記憶體自動釋放。即使發生異常,通過異常的棧展開過程也能將動態記憶體釋放。auto_ptr不支援new 陣列。
但是它有缺陷,stl容器在分配記憶體的時候,必須要能夠拷貝構造容器的元素。而且拷貝構造的時候,不能修改原來元素的值。而auto_ptr在拷貝構造的時候,一定會修改元素的值。所以stl元素不能使用auto_ptr。
所以最好不要使用。
下面是**實現:
[cpp]
view plain
copy
template
<
class
t>
class
autoptr
autoptr()
:_ptr(null)
{}
autoptr(autoptr& a)
:_ptr(a._ptr)
~autoptr()
} autoptr& operator=(autoptr&a)
return
*this
; }
t& operator*()
t* getptr()
protected
: t *_ptr;
};
void
test()
intmain()
希望對大家有所幫助。
最後總結一下:
1、在可以使用 boost 庫時,不要使用 std::auto_ptr,因為其不僅不符合 c++ 程式設計思想,而且極容易出錯。
2、在確定物件無需共享的情況下,使用 boost::scoped_ptr(動態陣列使用boost::scoped_array)。
3、在物件需要共享的情況下,使用 boost::shared_ptr(動態陣列使用boost::shared_array)。
4、在需要訪問 boost::shared_ptr 物件,而又不想改變其引用計數的情況下,使用boost::weak_ptr。
c 智慧型指標
auto prt 它是 它所指向物件的擁有者 所以當自身物件被摧毀時候,該物件也將遭受摧毀,要求乙個物件只有乙個擁有者,注意 auto prt 不能使用new 來分配物件給他 include include using namespace std template void bad print au...
c 智慧型指標
很久沒寫部落格了,不知道如何表達了,哈哈.我先介紹一下深淺拷貝.class copy 此時a.ptr和b.ptr指向同乙個物件,當我們delete a.ptr時 b.ptr所指向的物件已經不存在了,要是我們引用b.ptr指向的物件也就會出問題了.深拷貝 把a.ptr所指向的物件拷貝乙份給b.ptr ...
c 智慧型指標
記得前不久有一次面試被問到智慧型指標的實現,當時對智慧型指標只是聽說但沒有了解過,就亂七八糟地說了一遍。今天寫了一遍智慧型指標,用了引用計數的概念。主要思想就是,用乙個新類對原本需要的型別進行了一層封裝,這個新類中儲存了原本的物件指標和乙個引用計數的指標,之所以全部用指標來儲存,就是因為會出現多個新...