Posted on 2006-02-06 01:11
Tommy Liang 阅读(450)
评论(0) 编辑 收藏 引用 所属分类:
泛型编程与设计模式
在编译时刻,在Conversion类中产生两个常数(编译器帮忙计算)
template <class T,class U>
class Conversion
{
//
public:
enum { exists2Way = exists && Conversion<U,T>::exists };
enum { sameType = false };
}; 一个是 exists2Way,表示是否可以两个类型互相转换,
sameType 表示 T和U是否同一个类型。
不过,虽然书里这么说,我怎么都搞不懂为什么这样可以,测试也是不对的,难道这个sameType的写法还有别的奥妙?
不过下面这个偏特的写法倒是比较容易理解:
template <class T>
class Conversion<T,T>
{
public:
enum { exists = 1,exists2Way = 1,sameType = 1 };
}; 这个测试是OK的。
有了这几个常数,要决定两个class之间是否存在继承关系就比较容易了:
#define SUPERSUBCLASS(T,U) \
(Conversion<const U*, const T*>::exists && \
!Conversion<const T*, const void*>::sameType) 如果U是public继承自T,或者T和U是同一个类,那么SUPERSUBCLASS(T,U)传回true,这里是把某个class视为自己的超类,更严谨的做法是:
#define SUPERSUBCLASS_STRICT(T,U) \
(SUPERSUBCLASS(T,U) && \
!Conversion<const T, const U>::sameType) 即排除T与U是同一个类型的情况。
另外,加上 const 是为了 防止因为 const 而导致转型失败,对于已经是const的东西再const一次的话后面一次的const会忽略掉。
再,这个宏的名字很清晰,就是 超类--子类, 前面那个T是超类,U是子类,这个命名比 INHERITS要好。