智能指標(OSG源碼摘錄)

來源:互聯網
上載者:User

智能指標只是對指標添加引一個引用計數(_refCount).當new一個對象(即將對象賦予

ref_ptr<>變數)時_refCount加1.將ref_ptr<>變數指向其它的對象或者將其釋放(超出其

生命範圍,如局部變數)時,執行Referenced::unref(),_refCount會減1,此時如果

_refCount為0表明此對象已經沒有引用,可刪除,delete this;會調用解構函式

~Referenced(),並釋放記憶體資源.
template<class T>
class ref_ptr
{
    public:
        typedef T element_type;

        ref_ptr() : _ptr(0) {}
        ref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); }//建構函式2
     
        inline ref_ptr& operator = (T* ptr)
        {
            if (_ptr==ptr) return *this;
            T* tmp_ptr = _ptr;
            _ptr = ptr;
            if (_ptr) _ptr->ref();//添加新進的
            // unref second to prevent any deletion of any object which might
            // be referenced by the other object. i.e rp is child of the
            // original _ptr.
            if (tmp_ptr) tmp_ptr->unref();//釋放原來的
            return *this;
        }

 T* get() const { return _ptr; }

        T& operator*() const { return *_ptr; } 
        T* operator->() const { return _ptr; }      //指標重載

        T* _ptr;//類資料成員
};
void Referenced::unref()
{
 ...
 if ( ...)
 { 
  delete this;//會調用解構函式~Referenced(),並釋放記憶體空間
 }
}

調用時:
osg::ref_ptr< osg::Group > root= new osg::Group();//建立對象,調用ref_ptr的操作

符重載函數ref_ptr& operator = (T* ptr),並將其轉化為指標指向的值. 此時記憶體中

Group的引用計數為1.
root.get();//智能指標的成員函數

osg::ref_ptr< osg::Geode >  g= new osg::Geode();//記憶體中Geode的引用計數為1.
osg::ref_ptr< osg::Node >  g= new osg::Geode();//ref_ptr的=操作符重載(添加新進

的,釋放原來的),上一行中的Geode的引用計數變減1,變為0,此行中建立的Node的引用計數

加1,變為1.

root->addChild( g);//智能指標指向的值的函數.此時Node的引用計數加1,變為2,因為引

用它的對象又多了一個(root).
------------------------------------------------------------
下面是一個.和->操作符兩種符號能同時使用的例子:
template<class T>
class ref_ptr
{
public:
       
  ref_ptr(T* ptr) : _ptr(ptr) { }//建構函式

        T* operator->() const { return _ptr; }      //指標重載

  T* get() const { return _ptr; }

protected:
        T* _ptr;//類資料成員
};

class CA
{
public:
 void Fun()
 {
  cout<< "tm\n";
 }
};

class CA
{
public:
 void Fun()
 {
  cout<< "tm\n";
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 ref_ptr< CA> pi( new CA);
 
 pi.get();//對象本身就有.操作符
 pi->Fun();//重載的指標操作符,如果ref_ptr類中不對指標操作符進行重載,則

會報錯.pi->後直接接T的成員函數,不能是pi->()或pi->()->Fun()等.
}

===========
附:指標操作符(->)重載:

重載operator->(),返回普通對象指標,稱為間接(Dereferencing),可形成“智能指標

”機制(即對象->函數(),如C c; c->Fun(),這需要C類對指標操作符進行重載)。這樣

方便操作,也可不用。對於obj->member;,operator ->為一元尾碼運符,可作兩種解釋


①如obj為指標,將尋找緊隨其後的類成員(或函數)標識符,找不到就出錯,這也是最常

見的用法。
②如obj為(定義的智能指標)對象,將解釋為(obj.operator->())->member。若obj類未

重載operator->()則出錯;當重載了X operator ->()時,如果傳回型別X為指標,則進入

①狀態;如果傳回值類型仍為對象,再進入②狀態,判斷是否可迴圈。

傳回值應該為兩種:①指標,並找到成員標誌符;②定義了operator->()的對象,將迴圈

迭代。否則出錯。
具體樣本見於《C++ Primer》14.6節與《C++ Programming Language》11.10章節。
如上面代碼中的pi->Fun();即相當於是(pi.operator->())->Fun()。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.