|
/**/
/*
*******************************************************************
????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,這是標(biāo)準(zhǔn)規(guī)定的
????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( );
????
//
?返回一個(gè)T型別的值
????
static
?T?MakeT();

public
:

????
//
?exists的值反映了T是否可以轉(zhuǎn)換為U
????
//
?MakeT首先返回一個(gè)T型別的值,?傳入Test()中
????
//
?如果編譯器確定T可以轉(zhuǎn)換為U,那么調(diào)用返回Small的Test函數(shù)
????
//
?否則調(diào)用返回Big的Test函數(shù),則sizeof(Big)?!=?sizeof(Small)
????
//
?對(duì)于一般的型別如int,?char,double,float而言只是進(jìn)行隱性的轉(zhuǎn)換
????
//
?但是對(duì)于傳入類指針的情況而言,那么派生類的指針可以轉(zhuǎn)換為基類的指針
????
//
?也正是基于這一點(diǎn)可以作為檢查兩個(gè)類是否有繼承關(guān)系的技巧
????
enum
?
 ????
{
????????exists?
=
?
sizeof
(Test(MakeT()))?
==
?
sizeof
(Small)
????}
;

????
//
?型別T,U是否可以雙向轉(zhuǎn)換
????
enum
????
{
????????exists2Way?
=
?exists?
&&
?Conversion
<
U,?T
>
::exists
????}
;

????
//
?是否是同一個(gè)型別
????
enum
????
{
????????sameType?
=
?
false
????}
;
}
;

//
?針對(duì)同一個(gè)型別的模版偏特化類
template?
<
class
?T
>
class
?Conversion
<
T,?T
>
{
public
:
????
enum
????
{
????????exists?
=
?
1
,
????????exists2Way?
=
?
1
,
????????sameType?
=
?
1
????}
;
}
;

//
?檢查U是否是T的派生類的宏
//
?第一條語句檢查是否存在U*向T*的轉(zhuǎn)換,如果存在上述關(guān)系那么派生類指針U*可以轉(zhuǎn)換為基類指針T*
//
?第二條檢測(cè)派生類指針是不是和void*是一個(gè)型別的
#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代碼里面了,我想無需做太多的解釋,直接看代碼就好了。
|