设有三个源文件 abt.h, a.h, b.h 分别如下:ABT.htemplate<class TYPE, class TBase>
class ABT
{
private:
protected:
TYPE m_tType;
public:
ABT()
{
//这里有 __TYPEA__, __TYPEB__ 必须定义任一个的检查
m_tType = NULL;
} void Fun(.....)
{
#ifdef __TYPEA__
reutrn FunctionA( m_tType, .... );
#else
reutrn FunctionB( m_tType, .... );
#endif
}
}
--------------------------------------A.h#ifdef __TYPEA__
#error Stop!!!
#endif#define __TYPEA__
#include "ABT.h"class A : public ABT< TYPEA, A >
{
......
}#undef __TYPEA__
---------------------------------------
B.h#ifdef __TYPEB__
#error Stop!!!
#endif#define __TYPEB__
#include "ABT.h"class B : public ABT< TYPEB, B >
{
......
}#undef __TYPEB__在我的工程里面,
如果只
#include "A.h" 或 #include "B.h"一切OK!但是:
如果在我的工程里面,这样 #include "A.h"
#include "B.h"A a;
B b;a.Fun();
b.Fun();只有 __TYPEA__
有效, FunctionA,调用了TYPEB
,类型出错如果#include "B.h"
#include "A.h"A a;
B b;a.Fun();
b.Fun();只有 __TYPEB__
有效
, FunctionB,调用了TYPEA,类型出错???????????????????#undef 不起作用,还是我的写法有问题,还是.................至于为什么样这样做,因为 有一些可供调用的类似
FunctionA
FunctionB
函数,除了名称不同,第一个参数的类型不同以外,其他的参数,包括返回值是一模一样的。分没了,不好意思。
class ABT
{
private:
protected:
TYPE m_tType;
public:
ABT()
{
//这里有 __TYPEA__, __TYPEB__ 必须定义任一个的检查
m_tType = NULL;
} void Fun(.....)
{
#ifdef __TYPEA__
reutrn FunctionA( m_tType, .... );
#else
reutrn FunctionB( m_tType, .... );
#endif
}
}
--------------------------------------A.h#ifdef __TYPEA__
#error Stop!!!
#endif#define __TYPEA__
#include "ABT.h"class A : public ABT< TYPEA, A >
{
......
}#undef __TYPEA__
---------------------------------------
B.h#ifdef __TYPEB__
#error Stop!!!
#endif#define __TYPEB__
#include "ABT.h"class B : public ABT< TYPEB, B >
{
......
}#undef __TYPEB__在我的工程里面,
如果只
#include "A.h" 或 #include "B.h"一切OK!但是:
如果在我的工程里面,这样 #include "A.h"
#include "B.h"A a;
B b;a.Fun();
b.Fun();只有 __TYPEA__
有效, FunctionA,调用了TYPEB
,类型出错如果#include "B.h"
#include "A.h"A a;
B b;a.Fun();
b.Fun();只有 __TYPEB__
有效
, FunctionB,调用了TYPEA,类型出错???????????????????#undef 不起作用,还是我的写法有问题,还是.................至于为什么样这样做,因为 有一些可供调用的类似
FunctionA
FunctionB
函数,除了名称不同,第一个参数的类型不同以外,其他的参数,包括返回值是一模一样的。分没了,不好意思。
void Fun(.....)
实现为虚函数
类ABT 只提供接口
类A和B实现功能。你这么定义宏会把 类ABT 弄傻的。
void Fun(.....)
{
#ifdef __TYPEA__
reutrn FunctionA( m_tType, .... );
#else
reutrn FunctionB( m_tType, .... );
#endif
}
该函数会被编译器,编译到一个过程中,而非两个?
实现为虚函数 至于为什么不用虚函数 ,就是因为虚函数开销开大,发果是多继承的模式。上面的我当然可以改成虚函数的,甚至不用虚函数,单独封装 A, B,不通过继承 ABT 的方式。-----------------------------------------
你这么定义宏会把 类ABT 弄傻的。
void Fun(.....)
{
#ifdef __TYPEA__
reutrn FunctionA( m_tType, .... );
#else
reutrn FunctionB( m_tType, .... );
#endif
}
该函数会被编译器,编译到一个过程中,而非两个?
------------------------------------------编译器不会这么傻的啦。就好比 _UNICODE, _DEBUG 宏。都是这样用的。如果你的工程是 unicode 模式, 会自动定义 _UNICODE,对应的 TCHAR ,会处理成 WCHAR,你对 SetWindowText 系统函数的调用,实际上是调用的 SetWindowTextW。如果你的工程是 非unicode 模式, 不会自动定义 _UNICODE,对应的 TCHAR ,会处理成 CHAR,你对 SetWindowText 系统函数的调用,实际上是调用的 SetWindowTextA。
如果你的工程是 _DEBUG 模式,什么断言呀,才会执行。
如果你的工程是 非_DEBUG 模式,什么断言呀,根本就不会参与编译。看看 VC 自带的 .h 头文件,你就会发现非常非常多的 这样的宏定义。
#include "ABT.h" class A : public ABT < TYPEA, A >
{
......
} #undef __TYPEA__ 我现在就疑问就是:编译器在编译类A时, 实例化模板 ABT 时,__TYPEA__ 起作用,编译完类A 后, 因为 #undef __TYPEA__ ,__TYPEA__ 相当于没有定义。编译器在编译类B时, 实例化模板 ABT 时,__TYPEB__ 起作用,编译完类B 后, 因为 #undef __TYPEB__ ,__TYPEB__ 相当于没有定义。类A,类B,编译器总得一个一个编译吧。但是奇怪的就是:#undef ,好象没起作用。
{
//这里有 __TYPEA__, __TYPEB__ 必须定义任一个的检查
m_tType = NULL;
} 在这里,我写了一个检查,它的作用就是:如果 __TYPEA__, __TYPEB__ 同时被定义了,就报错。
如果 __TYPEA__, __TYPEB__ 一个都没有被定义,也报错。就是保证, ABT 模板实例化的时候,__TYPEA__, __TYPEB__,有且仅有一个被定义。
{
#ifdef __TYPEA__
reutrn FunctionA( m_tType, .... );
#else
reutrn FunctionB( m_tType, .... );
#endif
} 所以这里的 #else 里,我不用再判断 __TYPEB__ 是否被定义。