1.委託的概念:
委託和複合非常相似,也是一個類含有has-a一個東西,但是這種擁有很虛,我們不知道何時纔會擁有。只在我想
要用到這個東西的時候纔去調用,這是與複合的不同。委託的另外一個術語就很明瞭:Compositon by reference
含有指針的複合,爲什麼不是by point,因爲約定俗成,就是by reference。
舉個例子:
class StringRep;
class String
{
public:
String();
String(const chat* s);
String(const String& s);
String &operator=(const String& s);
~String();
....
private:
StringRep* rep;
};
從壽命上來看,複合關係下的壽命是同步的,同時創建,同時死亡。而委託不同步。
從委託上來看,委託方也就是String只是一個對外的接口,而實現的功能全都委託給StringRep來做。
這種寫法成爲:pimpl (point to implementation),我有一根指針指向一個替我實現所有功能的類。
也成爲 Handle/Body 左邊爲Handle,右邊爲Body。
這種寫法實現,委託方對外不變,受委託方變。也就是受委託方變動不會影響客戶端的東西,也稱爲編譯防火牆。
2.關於這種寫法的一些原理以及處理
StringRep代碼:
#include "String.hpp"
namespace
{
class StringRep
{
friend class String;
StringRep(const char* s);
~StringRep();
int count;
char* rep;
};
}
String::String(){ .... }
...
可以看到StringRep中的數據由count(圖中的n)與一個字符指針rep。n外的大圓圈就是StringRep。
如圖由三個字符串都指向hello,這個n將會是3.從共享上來看,內存就節省了。這就是Handle/Body的實現,可以做出reference counting共享的原理。
那麼當我a要去改變hello,這個時候就會copy一份給a去更改,bc依然共享。這種叫做copy on write。