程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++沉思錄讀書筆記(7章)-句柄:第二部分

C++沉思錄讀書筆記(7章)-句柄:第二部分

編輯:C++入門知識

 

上一回討論的句柄技術有一個明顯的缺點:為了將句柄捆綁到類T的對象上,必須要新定義一個具有類型為T的成員對象的新類。

這個毛病相當麻煩,如果想新設計一個類的句柄類,就需要新定義兩個類。

 

C++之父提到過一種定義句柄類的技術可以彌補這一個缺點,主要思想就是將引用技術從數據中分離出來,把引用計數放到句柄類自己的對象之中。

示例代碼如下所示:

#include <iostream> 

using namespace std; 

//----------------------------------------- 

class Point 

private: 

    int xval,yval; 

public: 

    Point():xval(0),yval(0){} 

    Point(int x,int y):xval(x),yval(y){} 

    int x()const{return xval;} 

    int y()const{return yval;} 

    Point& x(int xv){xval=xv;return *this;} 

    Point& y(int yv){yval=yv;return *this;} 

}; 

//------------------------------------------------------ 

 

class UseCount 

private: 

    int* p; 

public: 

    UseCount(); 

    UseCount(const UseCount&); 

    UseCount& operator=(const UseCount&); 

    ~UseCount(); 

    bool only(); 

    bool reattach(const UseCount&); 

    bool make_only(); 

}; 

UseCount::UseCount():p(new int(1)){} 

UseCount::UseCount(const UseCount&u):p(u.p){++*p;} 

UseCount::~UseCount() 

    if (--*p==0) 

    { 

        delete p; 

    } 

bool UseCount::only() 

    return *p==1; 

bool UseCount::reattach(const UseCount& u) 

    ++*u.p; 

    if (--*p==0) 

    { 

        delete p; 

        p=u.p; 

        return true; 

    } 

    p=u.p; 

    return false; 

bool UseCount::make_only() 

    if (*p==1) 

        return false; 

    --*p; 

    p=new int(1); 

    return true; 

//------------------------------------------- 

 

class Handle 

private: 

    Point* p; 

    UseCount u; 

public: 

    Handle(); 

    Handle(int,int); 

    Handle(const Point&); 

    Handle(const Handle&); 

    Handle& operator =(const Handle&); 

    ~Handle(); 

    int x()const; 

    Handle&x(int); 

    int y()const; 

    Handle&y(int); 

}; 

Handle::Handle():p(new Point){} 

Handle::Handle(int x,int y):p(new Point(x,y)){} 

Handle::Handle(const Point&p0):p(new Point(p0)){} 

Handle::Handle(const Handle&h):u(h.u),p(h.p){} 

Handle::~Handle() 

    if (u.only())  

    { 

        delete p; 

    } 

Handle& Handle::operator=(const Handle &h) 

    if (u.reattach(h.u)) 

        delete p; 

    p=h.p; 

    return *this; 

    /* //自定義版本不使用reattach輔助方法,自認為更容易理解,但很丑陋

    (*(h.u.p))++;

    if(*(u.p) == 1)

    {

        delete p;

        delete u.p;

    }

    else

        (*(u.p))--;

    u.p = h.u.p;

    p = h.p;    

    return *this;

    */ 

int Handle::x()const 

    return p->x(); 

int Handle::y()const 

    return p->y(); 

Handle& Handle::x(int x0) 

    if (u.make_only()) 

        p=new Point(*p); 

    p->x(x0); 

    return *this; 

    /* //自定義版本,不使用輔助方法make_only,自認為更容易理解,但很丑陋

    if(*(u.p) == 1)

        p->x(x0);

    else

    {

        (*(u.p))--;

        u.p = new int(1);

        p = new Point(*p);

        p->x(x0);

    }

    retrun *this;

    */ 

Handle& Handle::y(int y0) 

    if (u.make_only()) 

        p=new Point(*p); 

    p->y(y0); 

    return *this; 

    /* //自定義版本,不使用輔助方法make_only,自認為更容易理解,但很丑陋

    if(*(u.p) == 1)

        p->y(x0);

    else

    {

        (*(u.p))--;

        u.p = new int(1);

        p = new Point(*p);

        p->y(x0);

    }

    retrun *this;

    */   

//--------------------------------------------------- 

 

int main() 

    Handle h(3,4); 

    Handle h2 = h; 

    h2.x(5);  

    int n = h.x(); 

    cout<<n<<endl; 

    return 0; 

 

 

這個策略的一個重要優勢:UseCount類可以在不了解其使用者任何信息的情況下與之合為一體。這樣一來,我們就可以把這個類當成句柄實現的一部分,與各種不同的數據結構協同工作。

 

作者 yucan1001

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved