C++的語義類型和弱引用

C++中存在兩種語義:值語義(value sematics)和對象語義(object sematic),對象語義也可以叫做引用語義(reference sematics)。
值語義,指的是對象的拷貝與原對象無關,就像拷貝int一樣,C++的常用類型數據等都是值語義。
對象語義,指的是面向對象意義下的對象,是禁止拷貝的。

在設計一個類的時候該類是否可以被拷貝(即具備拷貝構造函數),取決於拷貝後的語義是否成立,比如一個Thread類,拷貝後系統中並不會啓動另外一個線程,所以拷貝是禁止的。
同樣類似於Employee僱員類也是。

C++最大的問題是內存越界,沒有自動垃圾內存回收機制,當越界時,程序就會core dump,這是最頭疼的。很多情況都是由懸掛指針(野指針)引起的。

在多線程程序中,一個對象如果被多個線程訪問,一般使用shared_ptr,通過引用計數來保證對象不被錯誤的釋放導致其他線程訪問出現問題。
但這種引用計數解決不了循環引用的問題,有如下代碼:
父類Parent和子類Child,均有指向對方的指針
  1. Class Parent  
  2. {  
  3. public:  
  4.     // ...  
  5. private:  
  6.     shared_ptr<Child> m_child;  
  7. }  
  8.   
  9.   
  10. Class Child  
  11. {  
  12. public:  
  13.     // ...  
  14. private:  
  15.     shared_ptr<Parent> m_parent;  
  16. }  
這樣由於兩個類之間互相引用,它們的計數都是1,最後誰也不會被釋放,就導致了內存泄漏。

一般解除循環引用有三種辦法:
1.手動釋放
2.如果Parent擁有Child,即Parent的生存期比Child大,那麼Child就使用一個普通的指針
3.使用弱引用的智能指針打破循環引用。

強引用:當至少有一個強引用時,對象就不能被釋放。shared_ptr就是如此。
弱引用:它僅僅是對象存在時候的引用,當對象不存在時弱引用能夠檢測到,從而避免非法訪問,弱引用也不會修改對象的引用計數。
  1. template<typename T> class weak_ptr  
  2. {  
  3.     public:  
  4.         template <typename Y>  
  5.         weak_ptr(const shared_ptr<Y>& r);  
  6.   
  7.         weak_ptr(const weak_ptr& r);  
  8.   
  9.         ~weak_ptr();  
  10.   
  11.         T* get() const;   
  12.         bool expired() const;   
  13.         shared_ptr<T> lock() const;  
  14. };  
定義變量:
shared_ptr<T>  t(new T);
weak_ptr<T> ptr(t); // t爲一個T對象 
則當t被銷燬時,ptr 被自動置爲無效。使用方法如下:
if ( shard_ptr<T>  safePtr  = ptr.lock() )  safePtr->Fun();
weak_ptr必須從一個boost::share_ptr或另一個boost::weak_ptr轉換而來,這也說明,進行該對象的內存管理的是那個強引用的boost::share_ptr。boost::weak_ptr只是提供了對管理對象的一個訪問手段。
弱引用指針可以有效的解除循環引用,但這種方式必須在程序員能預見會出現循環引用的情況下才能使用,也可以是說這個僅僅是一種編譯期的解決方案,如果程序在運行過程中出現了循環引用,還是會造成內存泄漏的。
轉載地址:http://blog.csdn.net/pecywang/article/details/8571096
發佈了8 篇原創文章 · 獲贊 32 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章