C++面試題——智能指針的原理和實現

     1,你知道智能指針嗎?智能指針的原理。

     2,常用的智能指針。
     3,智能指針的實現。

  1答案:智能指針是一個類,這個類的構造函數中傳入一個普通指針,析構函數中釋放傳入的指針。智能指針的類都是棧上的對象,所以當函數(或程序)結束時會自動被釋放,

     2, 最常用的智能指針: 

              1)std::auto_ptr,有很多問題。 不支持複製(拷貝構造函數)和賦值(operator =),但複製或賦值的時候不會提示出錯。因爲不能被複制,所以不能被放入容器中。

              2) C++11引入的unique_ptr, 也不支持複製和賦值,但比auto_ptr好,直接賦值會編譯出錯。實在想賦值的話,需要使用:std::move。

               例如:

                    std::unique_ptr<int> p1(new int(5));
                    std::unique_ptr<int> p2 = p1; // 編譯會出錯
                    std::unique_ptr<int> p3 = std::move(p1); // 轉移所有權, 現在那塊內存歸p3所有, p1成爲無效的指針.

              3) C++11或boost的shared_ptr,基於引用計數的智能指針。可隨意賦值,直到內存的引用計數爲0的時候這個內存會被釋放。

              4)C++11或boost的weak_ptr,弱引用。 引用計數有一個問題就是互相引用形成環,這樣兩個指針指向的內存都無法釋放。需要手動打破循環引用或使用weak_ptr。顧名思義,weak_ptr是一個弱引用,只引用,不計數。如果一塊內存被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該內存,內存也會被釋放。所以weak_ptr不保證它指向的內存一定是有效的,在使用之前需要檢查weak_ptr是否爲空指針。

     3, 智能指針的實現

      下面是一個基於引用計數的智能指針的實現,需要實現構造,析構,拷貝構造,=操作符重載,重載*-和>操作符。

  1. template <typename T>  
  2. class SmartPointer {  
  3. public:  
  4.     //構造函數  
  5.     SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){  
  6.         if(p)  
  7.             *_reference_count = 1;   
  8.         else  
  9.             *_reference_count = 0;   
  10.     }  
  11.     //拷貝構造函數  
  12.     SmartPointer(const SmartPointer& src) {  
  13.         if(this!=&src) {  
  14.             _ptr = src._ptr;  
  15.             _reference_count = src._reference_count;  
  16.             (*_reference_count)++;  
  17.         }  
  18.     }  
  19.     //重載賦值操作符  
  20.     SmartPointer& operator=(const SmartPointer& src) {  
  21.         if(_ptr==src._ptr) {  
  22.             return *this;  
  23.         }  
  24.         releaseCount();  
  25.         _ptr = src._ptr;  
  26.         _reference_count = src._reference_count;  
  27.         (*_reference_count)++;  
  28.         return *this;  
  29.     }  
  30.   
  31.     //重載操作符  
  32.     T& operator*() {  
  33.         if(ptr) {  
  34.             return *_ptr;  
  35.         }  
  36.         //throw exception  
  37.     }  
  38.     //重載操作符  
  39.     T* operator->() {  
  40.         if(ptr) {  
  41.             return _ptr;  
  42.         }  
  43.         //throw exception  
  44.     }  
  45.     //析構函數  
  46.     ~SmartPointer() {  
  47.         if (--(*_reference_count) == 0) {  
  48.             delete _ptr;  
  49.             delete _reference_count;  
  50.         }  
  51.     }  
  52. private:  
  53.     T *_ptr;  
  54.         size_t *_reference_count;  
  55.         void releaseCount() {  
  56.         if(_ptr) {  
  57.             (*_reference_count)--;  
  58.                 if((*_reference_count)==0) {  
  59.                     delete _ptr;  
  60.                     delete _reference_count;  
  61.                 }  
  62.         }  
  63.         }  
  64. };  
  65.   
  66. int main()   
  67. {  
  68.     SmartPointer<char> cp1(new char('a'));  
  69.     SmartPointer<char> cp2(cp1);  
  70.     SmartPointer<char> cp3;  
  71.     cp3 = cp2;  
  72.     cp3 = cp1;  
  73.     cp3 = cp3;  
  74.     SmartPointer<char> cp4(new char('b'));  
  75.     cp3 = cp4;  
  76. }  

發佈了32 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章