|
/**/
/*
*******************************************************************
created: 2007/02/04
filename: CanConverse.cpp
author: Lichuang
VC7,GCC下均可以编译通过
********************************************************************
*/
#include
<
iostream
>
using
namespace
std;

template
<
class
T,
class
U
>
class
Conversion

{
private
:
//
sizeof(char) == 1,这是标准规定的
typedef
char
Small;
//
sizeof(Big) == 2 * sizeof(char) > sizeof(char)
class
Big
{
char
dummy[
2
]; }
;
//
Test型别是U,返回值是Small
static
Small Test(U);
//
Test型别是任意型别,返回值是Big
static
Big Test( );
//
返回一个T型别的值
static
T MakeT();

public
:

//
exists的值反映了T是否可以转换为U
//
MakeT首先返回一个T型别的值, 传入Test()中
//
如果编译器确定T可以转换为U,那么调用返回Small的Test函数
//
否则调用返回Big的Test函数,则sizeof(Big) != sizeof(Small)
//
对于一般的型别如int, char,double,float而言只是进行隐性的转换
//
但是对于传入类指针的情况而言,那么派生类的指针可以转换为基类的指针
//
也正是基于这一点可以作为检查两个类是否有继承关系的技巧
enum

{
exists
=
sizeof
(Test(MakeT()))
==
sizeof
(Small)
}
;

//
型别T,U是否可以双向转换
enum
{
exists2Way
=
exists
&&
Conversion
<
U, T
>
::exists
}
;

//
是否是同一个型别
enum
{
sameType
=
false
}
;
}
;

//
针对同一个型别的模版偏特化类
template
<
class
T
>
class
Conversion
<
T, T
>
{
public
:
enum
{
exists
=
1
,
exists2Way
=
1
,
sameType
=
1
}
;
}
;

//
检查U是否是T的派生类的宏
//
第一条语句检查是否存在U*向T*的转换,如果存在上述关系那么派生类指针U*可以转换为基类指针T*
//
第二条检测派生类指针是不是和void*是一个型别的
#define
SUPERSUBCLASS(T, U) \
(Conversion
<
const
U
*
,
const
T
*>
::exists
&&
\
!
Conversion
<
const
T
*
,
const
void
*>
::sameType)

class
Base

{
}
;

class
Derive
:
public
Base

{
}
;

class
Test

{
}
;

int
main()

{
cout
<<
Conversion
<
double
,
int
>
::exists
<<
'
'
<<
endl;

if
(SUPERSUBCLASS(Base, Derive))

{
cout
<<
"
can derive\n
"
;
}
if
(
!
SUPERSUBCLASS(Base, Test))

{
cout
<<
"
Can not derive\n
"
;
}
return
0
;
}
说明的注释都在sample代码里面了,我想无需做太多的解释,直接看代码就好了。
|