设有三个源文件 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
函数,除了名称不同,第一个参数的类型不同以外,其他的参数,包括返回值是一模一样的。分没了,不好意思。

解决方案 »

  1.   

    环境vs2005 team suite sp1
      

  2.   

    建议将
    void   Fun(.....) 
    实现为虚函数
    类ABT 只提供接口
    类A和B实现功能。你这么定义宏会把 类ABT 弄傻的。
          void   Fun(.....) 
          { 
    #ifdef   __TYPEA__ 
                reutrn   FunctionA(   m_tType,   ....   ); 
    #else   
                reutrn   FunctionB(   m_tType,   ....   ); 
    #endif     
          } 
    该函数会被编译器,编译到一个过程中,而非两个?
      

  3.   

    void       Fun(.....)   
    实现为虚函数 至于为什么不用虚函数 ,就是因为虚函数开销开大,发果是多继承的模式。上面的我当然可以改成虚函数的,甚至不用虚函数,单独封装 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 头文件,你就会发现非常非常多的 这样的宏定义。
      

  4.   

    #define   __TYPEA__ 
    #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 ,好象没起作用。
      

  5.   

          ABT() 
          { 
    //这里有   __TYPEA__,   __TYPEB__   必须定义任一个的检查 
                m_tType   =   NULL;   
          } 在这里,我写了一个检查,它的作用就是:如果 __TYPEA__,   __TYPEB__ 同时被定义了,就报错。
    如果 __TYPEA__,   __TYPEB__ 一个都没有被定义,也报错。就是保证, ABT 模板实例化的时候,__TYPEA__,   __TYPEB__,有且仅有一个被定义。
      

  6.   

    void Fun(.....)       
    {       
    #ifdef               __TYPEA__       
           reutrn               FunctionA( m_tType,               ....               );       
    #else               
           reutrn               FunctionB( m_tType,               ....               );       
    #endif                       
    }  所以这里的 #else 里,我不用再判断 __TYPEB__ 是否被定义。