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


C++面試題(一)、(二)和(三)都搞定的話,恭喜你來到這里,這基本就是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, 智能指針的實現

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

    template <typename T>
    class SmartPointer {
    public:
        //構造函數
        SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
            if(p)
                *_reference_count = 1;
            else
                *_reference_count = 0;
        }
        //拷貝構造函數
        SmartPointer(const SmartPointer& src) {
            if(this!=&src) {
                _ptr = src._ptr;
                _reference_count = src._reference_count;
                (*_reference_count)++;
            }
        }
        //重載賦值操作符
        SmartPointer& operator=(const SmartPointer& src) {
            if(_ptr==src._ptr) {
                return *this;
            }
            releaseCount();
            _ptr = src._ptr;
            _reference_count = src._reference_count;
            (*_reference_count)++;
            return *this;
        }
     
        //重載操作符
        T& operator*() {
            if(ptr) {
                return *_ptr;
            }
            //throw exception
        }
        //重載操作符
        T* operator->() {
            if(ptr) {
                return _ptr;
            }
            //throw exception
        }
        //析構函數
        ~SmartPointer() {
            if (--(*_reference_count) == 0) {
                delete _ptr;
                delete _reference_count;
            }
        }
    private:
        T *_ptr;
            size_t *_reference_count;
            void releaseCount() {
            if(_ptr) {
                (*_reference_count)--;
                    if((*_reference_count)==0) {
                        delete _ptr;
                        delete _reference_count;
                    }
            }
            }
    };
     
    int main()
    {
        SmartPointer<char> cp1(new char('a'));
        SmartPointer<char> cp2(cp1);
        SmartPointer<char> cp3;
        cp3 = cp2;
        cp3 = cp1;
        cp3 = cp3;
        SmartPointer<char> cp4(new char('b'));
        cp3 = cp4;
    }


————————————————
版權聲明:本文為CSDN博主「tanglu2004」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/worldwindjp/article/details/18843087


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM