您的位置:首页 > 编程语言 > C语言/C++

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

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

#pragma once

template<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,就会选择这个版本。

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

不说了,免得误导人~~!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐