|
/**/
/*
******************************************************************* 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代码里面了,我想无需做太多的解释,直接看代码就好了。
|