c 智慧型指標

2021-08-01 08:01:44 字數 3398 閱讀 9984

在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 智慧型指標

記得前不久有一次面試被問到智慧型指標的實現,當時對智慧型指標只是聽說但沒有了解過,就亂七八糟地說了一遍。今天寫了一遍智慧型指標,用了引用計數的概念。主要思想就是,用乙個新類對原本需要的型別進行了一層封裝,這個新類中儲存了原本的物件指標和乙個引用計數的指標,之所以全部用指標來儲存,就是因為會出現多個新...