当前位置:编程学习 > C/C++ >>

C++沉思录读书笔记(7章)-句柄:第二部分

 

上一回讨论的句柄技术有一个明显的缺点:为了将句柄捆绑到类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; 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,