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

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

編輯:C++入門知識

 

創建代理會復制所代理的對象,如何避免這些復制呢?

       可以通過句柄(handle)類來實現。句柄類和智能指針有點類似,通過重載句柄類的*和->操作符,可將句柄類改造稱為智能指針。

       從效果上來說,handle就是一種只包含單個對象的容器,它通過允許多個handle對象指向同一個對象來避免復制。

       定義句柄類,我們還需要新定義一個類來容納被引用類對象的引用計數和被引用類對象本身。

示例代碼如下

#include <iostream> 

using namespace std; 

class Point 

private: 

    int xval, yval; 

public: 

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

    { 

        cout << "Point" << endl; 

    } 

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

    { 

        cout << "Point" << endl; 

    } 

    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; 

    } 

    ~Point() 

    { 

        cout << "~Point" << endl; 

    } 

}; 

class UPoint    //這個類對用戶來說是不可見的, 就是一個間接層 

    friend class Handle; 

    Point p;    //Point 對象 

    int u;     //計數器 

 

    UPoint():u(1)   //提供所有的point的構造方式 

    { 

        cout << "UPoint::" << u << endl; 

    } 

    UPoint(int x, int y):p(x, y), u(1) 

    { 

        cout << "UPoint::" << u << endl; 

    } 

    UPoint(const Point &p0) : p(p0), u(1) 

    { 

        cout << "UPoint::" << u << endl; 

    } 

    ~UPoint() 

    { 

        cout << "~UPoint::" << u << endl; 

    } 

}; 

class Handle 

private: 

    UPoint *up;    //和間接層UPoint打交道了 

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():up(new UPoint) 

    cout << "Handle::" <<up->u << endl;  

 

Handle::Handle(int x, int y):up(new UPoint(x, y)) //按創建Point的方式構造handle,handle->UPoint->Point 

    cout << "Handle::" <<up->u << endl; 

 

Handle::Handle(const Point &p):up(new UPoint(p)) //創建Point的副本 

    cout << "Handle::" <<up->u << endl; 

 

Handle::~Handle() 

    if(--up->u == 0) 

    { 

        cout << "~Handle::" <<up->u << endl; 

        delete up; 

    } 

    else 

    { 

        cout << "~Handle::" <<up->u << endl; 

    } 

 

Handle::Handle(const Handle &h):up(h.up) 

    ++up->u;       //此處復制的是handle,但是底層的point對象並未復制,只是引用計數加1 

    cout << "Handle::" <<up->u << endl; 

 

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

    ++h.up->u;       //右邊的對象引用計數加1,左邊的減1 

    if(--up->u == 0) 

        delete up; 

    up = h.up; 

    cout << "Handle::" <<up->u << endl; 

    return *this; 

 

int Handle::x() const 

    return up->p.x(); 

 

int Handle::y() const 

    return up->p.y(); 

 

Handle& Handle::x(int x0)//假設句柄為指針語義 

    up->p.x(x0); 

    return *this; 

 

Handle& Handle::y(int y0) 

    up->p.y(y0); 

    return *this; 

 

/*

Handle& Handle::x(int x0)//假設句柄為值語義(寫時復制)

{

    if(up->p != 1)

    {

        --up->u;

        up = new UPoint(up->p);

    }

    up->p.x(x0);

    return *this;

}

 

Handle& Handle::y(int y0)

{

    if(up->p != 1)

    {

        --up->u;

        up = new UPoint(up->p);

    }

    up->p.y(y0);

    return *this;

}

*/ 

 

void f(Handle h)   //測試函數,復制handle,但未復制Point 

    cout << h.x() << h.y() << endl; 

 

int main() 

    Handle h(3,5); 

    cout << h.x() << h.y() << endl; 

    f(h); 

 

    Point o(10,9); 

    Handle a(o); 

    Handle b(a); 

    return 0; 

}   

 

作者 yucan1001

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