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。