1、在【c++沉思錄】**類中,使用了**類,存在問題:
a、**複製,每次建立乙個副本,這個開銷有可能很大
b、有些物件不能輕易建立副本,比如檔案
2、怎麼解決這個問題?
使用引用計數控制代碼,對動態資源封裝,控制代碼包含指標,多個控制代碼可以指向同乙個物件。複製的時候,只是複製控制代碼的指標。
3、使用引用計數控制代碼,是為了避免不必要的物件複製,因此我們要知道有多少個控制代碼繫結到當前物件,也就是引用計數,
這樣才能確定何時可以釋放資源。
4、需要注意的是:引用計數不能是控制代碼的一部分,如果怎麼做,當前控制代碼必須知道指向同乙個物件的其他控制代碼,引用計數也要保持一致。
同時,引用計數不能成為物件的一部分,如果這樣做,要求我們重寫已經存在的物件類。
5、以point類為例說明,解決辦法是:增加乙個新的類upoint,包含point物件和引用計數u,如下:
class point
point(int x,int y):_x(x),_y(y){}
point(const point& rhs):_x(rhs._x),_y(rhs._y){}
point& setx(int x)
int getx()
point& sety(int y)
int gety()
private:
int _x;
int _y;
};#include "point.h"
// upoint的目的是對point和引用計數封裝,使用者是不可見的
class upoint
upoint(int x,int y)
upoint(const point& rhs)
};6、現在考慮handle_1的實現細節,
#include "u_point.h"
class handle_1
handle_1(int x,int y):_up(new upoint(x,y)){}
handle_1(const point& rhs):_up(new upoint(rhs)){}
~handle_1()
// copy構造,複製指標,增加引用
handle_1(const handle_1& rhs)
// copy賦值,左邊減少引用計數,判斷是否delete,右邊增加引用計數,考慮自我賦值
handle_1& operator=(const handle_1& rhs)
return * this;
}int getx()
int gety()
handle_1& setx(int x)
handle_1& sety(int y)
private:
void addref(upoint* up) // 複製指標,增加引用
void subref() // 減少引用,判斷是否delete
}private:
upoint* _up;
};7、考慮下面的情況,
handle_1 h1(3,4);
handle_1 h2(h1);
h2.setx(5);
int dd = h1.getx();
dd的值是5,也就是說,多個控制代碼指向同乙個物件,避免了不必要的物件複製,實現的是 指標語義。但是對於上面的情況,往往不是使用者所期望的,
怎麼解決這個問題?
8、使用寫時拷貝,每次修改的時候重新建立乙個物件。也就是說,修改的時候變成值語義,原物件h1是不可變物件,使用h2修改,會導致重新建立乙個物件。
如下:handle_1& setx(int x)
else
return *this;
}handle_1& sety(int y)
else
return *this;
}
C 沉思錄 控制代碼類1
看了下 c 沉思錄 第六章的內容介紹的是控制代碼第一部分,採用引用計數器的方式減少記憶體的拷貝 動手敲了下 加深點印象,加了點注釋 class point point int x,int y xval x yval y int x const int y const point x int xv p...
C 沉思錄 控制代碼2
1 c 沉思錄 控制代碼1 存在問題 控制代碼為了繫結到point的物件上,必須定義乙個輔助類upoint,如果要求控制代碼繫結到point的子類上,那就存在問題了。2 有沒有更簡單的辦法呢?控制代碼使用point 直接繫結到point物件上 包括子類 為了保持多個控制代碼引用計數的一致性,使用in...
C 沉思錄 控制代碼類2
c 沉思錄 的第六章介紹了控制代碼類,第七章也介紹控制代碼類,不過這章介紹的是引用技術和物件資料分開的技術,有3個類handle,point和usecount組成 順便新增了點自己認為重要的注釋 使用三個資料結構取代第六章的兩個資料結構會增加了模組化的程度而沒有增加額外的複雜性 並不是很理解這句話的...