C++沉思錄-句柄類1

看了下《C++沉思錄》第六章的內容介紹的是句柄第一部分,採用引用計數器的方式減少內存的拷貝

動手敲了下代碼加深點印象,加了點註釋

class Point
{
public:
    ///無參數的構造函數的作用:對於要創建一個Point的數組來說,
    ///我們可能只採用一個帶缺省參數的構造函數
    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;
    }
private:
    int xval;
    int yval;
};

Point類代表的是座標系上的1個點,Point類有2個成員變量xval和yval,有2個構造函數,有獲取xval,yval這兩個值得函數x(),y(),有設置xval,yval這兩個值得函數x(),y()

-------------------句柄類------------------------------------------
class Handle
{
public:
    Handle();
    ~Handle();
    Handle(int x, int y);
    Handle(const Point &p0);

    Handle(const Handle& h0);
    Handle& operator=(const Handle& h0);

    int x() const;
    int y() const;
    Handle& x(int xval);
    Handle& y(int yval);
private:
    UPoint *up;
};

Handle::Handle():up(new UPoint()){}

Handle::~Handle()
{
    ///引用計數器沒有減到0,不釋放內存
    if (--up->u)
    {
        delete up;
        up = NULL;
    }
}

Handle::Handle(int x, int y):up(new UPoint(x, y)){}

Handle::Handle(const Point &p0):up(new UPoint(p0)){}

///拷貝構造函數,引用計數器++
Handle::Handle(const Handle& h):up(h.up)
{
    ++up->u;
}

///等號操作符,先遞增右側的引用計數器,再遞減左側引用計數器
///這一操作即使左右兩個句柄引用同一個UPoint對象也能正常工作
Handle& Handle::operator=(const Handle& h)
{
    ++h.up->u;
    if (--up->u == 0)
    {
        delete up;
    }

    up = h.up;

    return *this;
}

int Handle::x() const
{
    return up->p.x();
}

int Handle::y() const
{
    return up->p.y();
}

Handle& Handle::x(int xval)
{
    up->p.x(xval);

    return *this;
}

///指針語義
Handle& Handle::y(int yval)
{
    up->p.y(yval);

    return *this;
}


///值語義
/*
Handle h(3, 4);
Handle h2 = h;
h2.x(5);
int n = h.x();      ///是3還是5
Handle& Handle::x(int xval)
{
    if (up->u != 1)
    {
        --up->u;
        up = new UPoint(up->p)
    }

    up->p.x(xval);

    return *this;
}
*/

handle應該控制它所綁定的對象,就是由handle創建和銷燬對象,從效果上來講handle就是一種只包含單個對象的容器,如果不想暴露Point的具體操作,就必須明確的選擇讓handle類支持那些Point操作

----------------UPoint---------------------------
///爲什麼需要UPoint這個類?該類用來容納引用計數器和一個Point對象,
///這個類存粹是爲了實現而設計的

class UPoint
{
    ///這裏Hnandle需要訪問UPoint類的成員變量,所以聲明稱UPoint的友元,位置不要搞反了
    friend class Handle;

    UPoint():u(1){}
    UPoint(int x, int y):p(x, y), u(1){}
    UPoint(const Point& p0):p(p0), u(1){}

    Point p;
    int u;
};

/*
 * 句柄類可以避免內存的重複拷貝
 */

int main()
{
    Point p(7, 8);
    Handle h(p);

    Handle h2 = h;

    cout << h2.x() << " " << h2.y() << endl;

    cout << "**************TvT*****************" << endl;

    return 0;
}
 

這個句柄類有一個缺點就是引用計數器和對象本身是存放在UPoint中的

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章