学习C++设计新思维(泛型编程与设计模式之应用).pdf之继承关系检查

来源:互联网 发布:软件外包资质 编辑:程序博客网 时间:2024/04/27 21:24

ok!主题是:检查型别A与B是不是有继承关系,在本书的P38,下面直接上代码。

#pragma oncetemplate<class T, class U>class Conversion{typedef char Small;class Big{ char dummy[2]; };static Small Test(U);static Big Test(...);static T MakeT();public:enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };enum { exists2Ways = exists && Conversion<U, T>::exists };enum { sameType = false };};template<class T>class Conversion < T, T >{public:enum { sameType = true, exists = true, exists2Ways = true };};#define SUPERSUBCLASS(T, U)\(Conversion<const T*, const U*>::exists &&\!Conversion<const T*, const void*>::sameType)#define SUPERSUBCLASS_STRICT(T, U)\(SUPERSUBCLASS(T, U) &&\!Conversion<const T, const U>::sameType)

void chapter2_CI_CI(){cout << "<int->long>" << Conversion<int, long>::exists << "\n" << endl;cout << "<char->char*>" << Conversion<char, char*>::exists << "\n" << endl;cout << "<std::size_t->vector<int>>" << Conversion<std::size_t, std::vector<int>>::exists << "\n" << endl;class A{};class B : public A{};cout << "SUPERSUBCLASS(A, B):" << SUPERSUBCLASS(A, B) << endl;cout << "SUPERSUBCLASS(B, A):" << SUPERSUBCLASS(B, A) << endl;cout << "SUPERSUBCLASS(int, long):" << SUPERSUBCLASS(int, long) << endl;cout << "SUPERSUBCLASS(int, int):" << SUPERSUBCLASS(int, int) << endl;cout << "SUPERSUBCLASS(char, char*):" << SUPERSUBCLASS(char, char*) << endl << endl;cout << "SUPERSUBCLASS_STRICT(A, B):" << SUPERSUBCLASS_STRICT(A, B) << endl;cout << "SUPERSUBCLASS_STRICT(B, A):" << SUPERSUBCLASS_STRICT(B, A) << endl;cout << "SUPERSUBCLASS_STRICT(int, long):" << SUPERSUBCLASS_STRICT(int, long) << endl;cout << "SUPERSUBCLASS_STRICT(int, int):" << SUPERSUBCLASS_STRICT(int, int) << endl;cout << "SUPERSUBCLASS_STRICT(char, char*):" << SUPERSUBCLASS_STRICT(char, char*) << endl;}

<int->long>1
<char->char*>0
<std::size_t->vector<int>>0


SUPERSUBCLASS(A, B):0
SUPERSUBCLASS(B, A):1
SUPERSUBCLASS(int, long):0
SUPERSUBCLASS(int, int):1
SUPERSUBCLASS(char, char*):0


SUPERSUBCLASS_STRICT(A, B):0
SUPERSUBCLASS_STRICT(B, A):1
SUPERSUBCLASS_STRICT(int, long):0
SUPERSUBCLASS_STRICT(int, int):0
SUPERSUBCLASS_STRICT(char, char*):0
请按任意键继续. . .


上面是代码和运行结果。使用win7+vs2013.

----------------------

我也是才学模板的,所以涉及不深,也说不上什么来。错误之处请指正。

他的转换是依赖函数的重载机制的。

像代码:enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };使用MakeT方法的返回值传给方法Test,而Test有2个版本,所以编译器择优选择,如果可以匹配到static Small Test(U),则可以转换,负责编译器只能选择static Big Test(...);,这时就表示不能转换,同时再依赖于sizeof的大小检测。这里应该都明白了, 但是看你会有一个问题,A不能转换为B,但是要是2个大小一样怎么办?请看:typedef char Small;class Big{ char dummy[2]; };


同时在检测类型一致时,使用了类模板偏特化的机制,函数是没有偏特化的。但是好像可以使用TYPE2TYPE来填坑。

类:

template<class T>
class Conversion < T, T >

这个类模板的声明呢,跟代码里其他一个模板类的声明不一样,一个是template<class T, class U>,一个就是template<class T>,但是这个类却使用了 class Conversion < T, T >,这个就是偏特化,如果你要定义一个类对象,如:Conversion (int ,int),那么编译器会选择模板参数只有一个的,如果你定义Conversion (int ,long),他会选择有两个模板参数的。模板偏特化还可以让你这么定义:

template<class T>
class Conversion < T, int >

这样不管T是什么,如果第二个参数是int,就会选择这个版本。

----------------------

不说了,免得误导人~~!

0 0
原创粉丝点击