首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

Allocator类模板的奇怪定义(codeproject的代码),如下:解决方法

2012-02-26 
Allocator类模板的奇怪定义(codeproject的代码),如下://Policydrivenallocatorobjecttemplate typenameT,

Allocator类模板的奇怪定义(codeproject的代码),如下:
//Policy   driven   allocator   object
template <typename   T,   typename   Policy   =   StandardAllocPolicy <T> ,   typename   Traits   =   ObjectTraits <T>   >
class   Allocator   :   public   Policy,   public   Traits   {
private   :  
typedef   Policy   AllocationPolicy;
typedef   Traits   TTraits;

public   :   //   这里的重定义是必要的吗?
typedef   typename   AllocationPolicy::size_type   size_type;
typedef   typename   AllocationPolicy::difference_type   difference_type;
typedef   typename   AllocationPolicy::pointer   pointer;
typedef   typename   AllocationPolicy::const_pointer   const_pointer;
typedef   typename   AllocationPolicy::reference   reference;
typedef   typename   AllocationPolicy::const_reference   const_reference;
typedef   typename   AllocationPolicy::value_type   value_type;

public   :  
template <typename   U>
struct   rebind   {
typedef   Allocator <U,   typename   AllocationPolicy::rebind <U> ::other>   other;
};

public   :  
inline   explicit   Allocator()   {}
inline   ~Allocator()   {}
inline   Allocator(Allocator   const&   rhs):Traits(rhs),   Policy(rhs)   {}
template   <typename   U>
inline   explicit   Allocator(Allocator <U>   const&)   {}
template   <typename   U,   typename   P,   typename   T2>
inline   Allocator(Allocator <U,   P,   T2>   const&   rhs):Traits(rhs),   Policy(rhs)   {}

//memory   allocation
//这里allocate、deallocate是不是重复了,可以删除吗?
inline   pointer   allocate(size_type   cnt,   typename   std::allocator <void> ::const_pointer   hint   =   0)   {  
return   AllocationPolicy::allocate(cnt,   hint);
}
inline   void   deallocate(pointer   p,   size_type   cnt)   {  
AllocationPolicy::deallocate(p,   cnt);
}
};//end   of   class   Allocator

[解决办法]
模板在编译的时候,名字搜索规则是很复杂的。
前面的type重复,是为了避免误用外部空间里的类型定义。
后面一个去掉则问题不大。

有很多语法细节/编程风格的问题,不要钻得太深入。
[解决办法]
在一个模板中为一些类型参数起别名(typedef)已经是C++的习惯了。有什么用呢?看下面的代码:
//一个范型算法,通过交换两个容器的元素
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
??? temp; //这里该用什么类型声明呢?
??? begin1, end1;//还有这里?
??? begin2; //以及这里?
for(; begin1!=end1; ++begin1, ++begin2)
{
temp=*begin1;
*begin1=*begin2;
*begin2=temp;
}
}
由于在编写这个函数模板时我们不知道容器中元素的类型,以及容器的类型,那么,temp的类型也就无从确定了。但是,由于在容器中都声明了一些辅助类型,所以,我们的范型算法才得以实现:
template <class C1, class C2>
exch(C1& cnt1, C2& cnt2) {
C1::value_type temp; //容器通过类型别名给出了容器元素的类型
C1::iterator begin1, end1;//容器通过类型别名给出了迭代器的类型
C2::iterator begin2; // 同上
...
}
从上面的例子中,可以看出,类型别名typedef在范型编程中起到非常重要的作用,尽管他们乍看是没有必要的。推广到一般的模板组件,typedef将模板的使用者同模板的具体实现,在类型上隔离了。用户只需关心模板中某个类型的逻辑含义,而无需关心实际类型。此时,模板便可以对类型进行充分地泛化。
实际上这些typedef是模板接口的一部分。通过这种手段,可以使代码充分泛化,达到最高效编程的目的。


反过来,我们也可以认为,如果一种语言不能为类型取别名,那么可以断定这种语言无法实现真正的范型编程。
[解决办法]
继然是多重继承

你怎么不想想第二基类Traits中也是不是有那些类型呢

如果有,当然那些typedef是必要的


这个Allocator显然只是一个包装的类,成员函数都是对Policy成员函数的转调用

Allocator只是一个符合某种规范的壳,真正的操作由传给Policy的类来完成,这里提供了灵活性。
[解决办法]
是这样的,typedef typename AllocationPolicy::size_type size_type; 定义了Allocator::size。因为Allocator继承了Policy和Traits,而这两个类是可以由用户定义的。它们都可能定义了size_type等等。如果不做typedef,那么就潜藏着两个基类不能同时定义size_type等类型的规则,否则在使用Allocator时就有可能发生歧义。这种潜规则会加大编程复杂度,与设计Allocator的初衷背道而驰。因此,这个定义是必要的。
而且,首先定义AllocationPolicy,再用它定义Allocator::size_type等,可以方便今后的修改,提高可伸缩性。
allocator,deallocator则是编程语义明确性的考量。Allocator必须提供allocator和deallocator的接口。而这些接口将借助Policy的同名接口改变其行为。虽然目前的Allocator使用的是同一方式借助Policy的同名接口,但就Allocator和Policy的语义而言,同一方式不是必须的。因此,明确定义这两个接口,就是表达了“将来可能不采用同一方式”这一诉求。
虽然从实现上而言,由于Allocator继承了Policy,因而目前这两个接口是不必要的(注意按Traits的语义,它绝对不应该定义allocator和deallocator接口,和上面第一个问题不同,因此不会有二义性的发生)。但是这里的继承是一种实现手段,而非一般意义上的is-a关系,所以从语义角度不应该省略它们。在因为基类和派生类中,它们有着不同的语义。

热点排行