如何回答c++面試中關於智慧型指標的問題?
1、
什麼是智慧型指標?
2、
分析下常見的智慧型指標有哪些? 3
、實現乙個智慧型指標唄?
(沒具體說寫哪個,建議預設寫:unique_ptr)
1
、答:智慧型指標(smart pointer)是儲存指向動態分配(堆)物件指標的類,用於生存期控制,能夠確保自動正確的銷毀動態分配的物件,防止記憶體洩露(利用自動呼叫類的析構函式來釋放記憶體)。它的一種通用實現技術是使用引用計數(除此之外還有資源獨佔,如(auto_ptr),只引用,不計數(weak_ptr))。智慧型指標類將乙個計數器與類指向的物件相關聯,引用計數跟蹤該類有多少個物件共享同一指標。每次建立類的新物件時,初始化指標並將引用計數置為1;當物件作為另一物件的副本而建立時,拷貝建構函式拷貝指標並增加與之相應的引用計數;對乙個物件進行賦值時,賦值操作符減少左運算元所指物件的引用計數(如果引用計數為減至0,則刪除物件),並增加右運算元所指物件的引用計數;呼叫析構函式時,建構函式減少引用計數(如果引用計數減至0,則刪除基礎物件)。
2
、常見的智慧型指標以及解析:
auto_ptr
(1)它是c++標準庫提供的類模板,auto_ptr物件通過初始化指向由new建立的動態記憶體,它是這塊記憶體的擁有者,一塊記憶體不能同時被分給兩個擁有者(資源獨佔)。當auto_ptr物件生命週期結束時,其析構函式會將auto_ptr物件擁有的動態記憶體自動釋放。
(2)auto_ptr不能指向陣列,因為auto_ptr在析構的時候只是呼叫delete,而陣列應該要呼叫delete。(但uniquearray管理的是一段連續的空間,它也是防拷貝的,功能類似於vector。)
(3)auto_ptr不能作為容器物件,因為它不支援拷貝構造與賦值(出錯了也不容易發現),stl容器中的元素經常要支援拷貝,賦值等操作,在這過程中auto_ptr會傳遞所有權,那麼就會出錯。
unique_ptr
它是( c++
11引入的,前身是scoped_ptr,scoped_ptr是boost庫里的),也不支援拷貝構造和賦值,但比auto_ptr好,直接賦值會編譯出錯(與auto_ptr最大的不同就是類內私有的宣告了拷貝建構函式和賦值運算子過載,是針對auto_ptr的缺點而出現的)。
shared_ptr
c++11或boost的shared_ptr,基於引用計數的智慧型指標。可隨意賦值,直到記憶體的引用計數為0的時候這個記憶體會被釋放。環狀的鏈式結構可能會形成記憶體洩露(迴圈引用)
迴圈引用問題
(常問到哦)
為了解決類似這樣的問題,c++11引入了weak_ptr,來打破這種迴圈引用。
weak_ptr
c++11或boost的weak_ptr,弱引用。 引用計數有乙個問題就是互相引用形成環,這樣兩個指標指向的記憶體都無法釋放。需要手動打破迴圈引用或使用weak_ptr。顧名思義,weak_ptr是乙個弱引用,它是為了配合shared_ptr而引入的一種智慧型指標,它指向乙個由shared_ptr管理的物件而不影響所指物件的生命週期,也就是說,它只引用,不計數。如果一塊記憶體被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該記憶體,記憶體也會被釋放。所以weak_ptr不保證它指向的記憶體一定是有效的,在使用之前需要檢查weak_ptr是否為空指標。
weak_ptr並沒有過載operator->和operator *操作符,因此不可直接通過weak_ptr使用物件,典型的用法是呼叫其lock函式來獲得shared_ptr示例,進而訪問原始物件。
auto_ptr
的實現template
t>
class
autoptr
//採用資源的轉移方法管理記憶體,在它的拷貝構造和賦值運算子引起會出現問題
autoptr(autoptr
&ap)
:ptr(ap.ptr)
autoptr
&operator=(autoptr
&ap)
ptr= ap.ptr;
ap.ptr= null;
}return*this;
}t* operator*()
t* operator->()
voidget_ptr()
~autoptr()
}private:
t*ptr;
};voidfuntest()
//ap3
的ptr
指向的空間,所以沒法向
ap3賦值
int main()
unique_ptr
的實現template
t>
class
unique_ptr
//前身是
scoped_pt
,實現粗暴
—>
禁止轉移
-->
獨佔資源(只允許乙個指標管理資源) //
(禁止調拷貝構造和賦值運算子)
,它只能管理單個物件
t* operator*()
t* operator->()
voidget_ptr()
~unique_ptr ()
}private:
unique_ptr (unique_ptr
&ap);//
禁止拷貝構造
unique_ptr
&operator=(unique_ptr
&ap1);//
禁止賦值
t*ptr;
};//
為什麼unique_ptr
防拷貝的實現必須是私有的宣告? 1
、只給共有的宣告,不給定義。(使用者可以在類外重新給出定義) 2
、只給私有的定義(但是類內可以調拷貝構造和賦值運算子)
所以採用私有的宣告拷貝建構函式和賦值運算子過載函式實現
unique_ptr
的防拷貝
shared_ptr
的實現template
t>
class
share_ptr }
share_ptr(const
share_ptr
&ps)
:_p(ps._p)
,_pcount(ps._pcount)
}t* operator*()
t* operator->()
voidget_ptr()
~share_ptr()
}private:
t* _p;
int*_pcount;
};voidfuntest()
c 智慧型指標的問題 智慧型指標初探(一)
為什麼要有智慧型指標 在c 中,動態記憶體的管理一般是用一對運算子完成的 new和delete。new 在動態記憶體中為物件分配一塊空間並返回乙個指向該物件的指標。delete 指向乙個動態獨享的指標,銷毀物件,並釋放與之關聯的記憶體。使用new和delete動態記憶體管理經常會出現問題 忘記釋放記...
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 ...