《C++设计新思维》读书笔记(二)
1.5 Policies和Policy Classes
举例,定义一个policy生成对象:Creator policy 提供一个Create函数,返回一个指向新生T类型对象的指针。
我们有三种做法:
1 template<class T>
2 struct OpNewCreator{
3 static T* Create(){
4 return New T;
5 }
6 };
7 template <class T>
8 struct MallocCreator{
9 static T* Create(){
10 void* buf = std::malloc(sizeof(T));
11 if(!buf) return 0;
12 return new(buf) T; //定位new表达式,见《C++ primer》8.4.5, cuigang
13 }
14 };
15 template <class T>
16 struct PrototypeCreator{
17 PrototypeCreator(T* pObj =0):pPrototype_(pObj){}
18 T* Create(){
19 return pPrototype_? pPrototype_->Clone():0;
20 }
21 T* GetPrototype(){ return pPrototype_;}
22 void SetPrototype(T* pObj){pPrototype_ = pObj;}
23 private:
24 T* pPrototype_;
25 };
26
这些实作出来的policy称为policy classes,这个东西并不意图被单独使用,它们主要用于继承或被内含于其它classes。
一个类以复合或继承的方式使用先前定义的三个classes之一,例如
1 //Library code
2 template <class CreationPolicy>
3 class WidgetManager : public CreationPolicy{};
如果class采用一个或多个policies,我们称为hosts或host classes。
客户端如此实例化:
1 //Application code
2 typedef WidgetManager< OpNewCreator<widget> > MywidgetMgr;
让我们分析整个来龙去脉。无论何时,当一个MywidgetMgr对象需要产生一个widget对象时,它便调用它的policy子对象OpNewCreator<widget>所提供的Createv()。选择“生成策略”(Creation policy)是WidgetManager使用者的权利。藉由这样的设计,可以让WidgetManager使用者自行装配他所需要的机能。
这便是Policy-based class的设计主旨。
==============================
1 template <class T>
2 void* buf = std::malloc(sizeof(T));
3 void* buf = (void*)new T;
当T为基类,具有派生类时,两者申请的内存大小是不一致的,sizeof(T)不包括 virtual table 的大小。
——钟遥
//////////////////////////////
钟遥过虑了,以下代码
1 struct base{
2 int x;
3 base(){
4 std::cout<< "create a base."<<std::endl;
5 }
6 virtual void foo(){
7 std::cout<<"call base"<<std::endl;
8 };
9 };
10 struct test : public base{
11 int y;
12 test(){
13 std::cout<< "create a test."<<std::endl;
14 }
15 virtual void foo(){
16 std::cout<<"call test."<<std::endl;
17 }
18 void foo2(){};
19 };
20 /////////////////////////
21 int a = sizeof(test);
22 int b = sizeof(base);
23 std::cout<<"sizeof(test)="<< a << ", "<<"sizeof(base)=" << b << endl;
24 base* pa = new base;
25 base* pb = new test;
26 std::cout<<"---------"<<endl;
27 base* ppa = (base*)malloc(sizeof(base));
28 base* ppb = (base*)malloc(sizeof(test));
29 std::cout<<"---------"<<endl;
30 new(ppa) base;
31 new(ppb) test;
32 pa->foo();
33 pb->foo();
34 ppa->foo();
35 ppb->foo();
输出结果:
1 sizeof(test)=12, sizeof(base)=8
2 create a base.
3 create a base.
4 create a test.
5 ---------
6 ---------
7 create a base.
8 create a base.
9 create a test.
10 call base
11 call test.
12 call base
13 call test.