CG@CPPBLOG

/*=========================================*/
随笔 - 76, 文章 - 39, 评论 - 137, 引用 - 0
数据加载中……

《C++设计新思维》读书笔记(12)

2.7 编译期间侦测可转换性和继承性

在泛型编程中,经常遭遇一个问题:对于两个型别TU,如何得知U是否继承于T。我们需要在编译时发现这样的关系,而不必使用dynamic_cast——它会损耗执行期效率。

我们利用sizeof 重载函数。比如如下定义两个类型,和两个函数,一个函数接收U类型,一个接收任意类型。

1 typedef char Small;
2 class Big {char dummy[2];};
3 Small Test(U);
4 Big Test();//省略号参数函数

我们传一个T类型对象给Test函数,看它能不能转换为U

1 const bool convExists = sizeof(Test(T())) == sizeof(Small);

但如果T的缺省构造函数为私有,则会编译失败,所以我们用一个稻草人函数

1 T MakeT();
2 const bool convExists = sizeof(Test(MakeT())) == sizeof(Small);

我们注意,sizeof()里面的东西不需要具现,所以T对象,MakeT()Test()都不需要实作。它们根本不真正存在!!现在用class template包装起来。

 1 template<class T, class U>
 2 class Conversion
 3 {
 4     typedef char Small;
 5     class Big {char dummy[2];};
 6     static Small Test(U);
 7     static Big Test();
 8     static T MakeT();
 9 public:
10     // T可以转换为U
11     enum {exists = sizeof(Test(MakeT())) == sizeof(Small)};
12     // 可以双向转换
13     enum {exists2Way = exists && conversion<U, T>::exists };
14     enum {sameType = false};
15 };
16 //利用偏特化处理 sameType == true 情况
17 template<class T>
18 class Conversion<T, T>
19 {
20 public:
21     enum { exists = 1, exists2Way = 1, sameType = 1};
22 };

最后,我们可以根据这个来判断两个类之间是否有继承关系:

1 #define SUPER_SUB_CLASS(T, U)\
2            (Conversion<const U*const T*>::exists &&\
3            !Conversion<const T*const void*>::sameType)

如果U是共有继承于T,或者TU是同一型别,SUPER_SUB_CLASS(T, U)都传回true。这里加上const饰词的原因是,我们不希望因const而导致转换失败,对一个型别const两次,第二个const会被忽略。

posted on 2007-12-23 12:12 cuigang 阅读(210) 评论(0)  编辑 收藏 引用 所属分类: 《C++设计新思维》读书笔记


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理