巧用宏定义来简写C,C++代码

Vimer的程序世界 [ http://www.vimer.cn ]中看到这篇文章,对宏有了一个更深刻的了解,所以转载过来以便以后学习。

 

============== 以下为转载内容 ==============

今天在工作上遇到一个问题,觉得很有代表性, 特抽象如下:
通过设计模式的角度来说,就是模板方法,已经有一个基类,需要定义很多子类来实现其方法。
但是类名都只有一部分不同,且构造函数的入参也只有一部分不同。
如代码:
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
using namespace  std ;
class EMA
{
    
public:
        EMA(string a,string b,string c,string d,string e)
        {
            cout <<a<<
" , " <<b<< " , " <<c<< " , " <<d<< " , " <<e<<endl ;
        }
}
;
class  EMA4CGI_1ST: public EMA{
    
public:
        EMA4CGI_1ST():EMA(
                
" app_mng.1ST_EMA_AVG " ,
                
" app_mng.1ST_EMA_HWM " ,
                
" app_mng.1ST_EMA_TMO " ,
                
" app_mng.1ST_EMA_N " ,
                
" app_mng.1ST_EMA_RATIO "
                ){}
        ~EMA4CGI_1ST() {}
}
;
class  EMA4CGI_2ND: public EMA{
    
public:
        EMA4CGI_2ND():EMA(
                
" app_mng.2ND_EMA_AVG " ,
                
" app_mng.2ND_EMA_HWM " ,
                
" app_mng.2ND_EMA_TMO " ,
                
" app_mng.2ND_EMA_N " ,
                
" app_mng.2ND_EMA_RATIO "
                ){}
        ~EMA4CGI_2ND() {}
}
;
class  EMA4CGI_3RD: public EMA{
    
public:
        EMA4CGI_3RD():EMA(
                
" app_mng.3RD_EMA_AVG " ,
                
" app_mng.3RD_EMA_HWM " ,
                
" app_mng.3RD_EMA_TMO " ,
                
" app_mng.3RD_EMA_N " ,
                
" app_mng.3RD_EMA_RATIO "
                ){}
        ~EMA4CGI_3RD() {}
}
;
int  main( int  argc, const char *argv[])
{
    EMA4CGI_1ST()
;
    EMA4CGI_2ND() ;
    EMA4CGI_3RD() ;
    return  0 ;
}
输出如下:
app_mng.1ST_EMA_AVG,app_mng.1ST_EMA_HWM,app_mng.1ST_EMA_TMO,app_mng.1ST_EMA_N,app_mng.1ST_EMA_RATIO
app_mng.2ND_EMA_AVG,app_mng.2ND_EMA_HWM,app_mng.2ND_EMA_TMO,app_mng.2ND_EMA_N,app_mng.2ND_EMA_RATIO
app_mng.3RD_EMA_AVG,app_mng.3RD_EMA_HWM,app_mng.3RD_EMA_TMO,app_mng.3RD_EMA_N,app_mng.3RD_EMA_RATIO
非常恶心的代码,而且非常容易写错,如果是python,由于其本身自省的能力,所以不会存在这样的问题,但是C++可没有这种能力,所以我们只能寄希望与宏定义了。
直接来看一下我们改写的代码:
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
using namespace  std ;
class EMA
{
    
public:
        EMA(string a,string b,string c,string d,string e)
        {
            cout <<a<<
" , " <<b<< " , " <<c<< " , " <<d<< " , " <<e<<endl ;
        }
}
;
#define EMACLASS_DEFINITION(class_name)\
    class EMA4CGI_##
class_name: public EMA{\
        
public: \
            EMA4CGI_##class_name():EMA(\
                    
" app_mng. " #class_name " _EMA_AVG " ,\
                    
" app_mng. " #class_name " _EMA_HWM " ,\
                    
" app_mng. " #class_name " _EMA_TMO " ,\
                    
" app_mng. " #class_name " _EMA_N " ,\
                    
" app_mng. " #class_name " _EMA_RATIO " \
                    ){}\
            ~EMA4CGI_##class_name() {}\
    }
;
 
EMACLASS_DEFINITION(1ST)
EMACLASS_DEFINITION(2ND)
EMACLASS_DEFINITION(3RD)
 
int  main( int  argc, const char *argv[])
{
    EMA4CGI_1ST()
;
    EMA4CGI_2ND() ;
    EMA4CGI_3RD() ;
    return  0 ;
}
输入结果为:
app_mng.1ST_EMA_AVG,app_mng.1ST_EMA_HWM,app_mng.1ST_EMA_TMO,app_mng.1ST_EMA_N,app_mng.1ST_EMA_RATIO
app_mng.2ND_EMA_AVG,app_mng.2ND_EMA_HWM,app_mng.2ND_EMA_TMO,app_mng.2ND_EMA_N,app_mng.2ND_EMA_RATIO
app_mng.3RD_EMA_AVG,app_mng.3RD_EMA_HWM,app_mng.3RD_EMA_TMO,app_mng.3RD_EMA_N,app_mng.3RD_EMA_RATIO
OK,问题解决!

可能问题本身在不同的场景下有多种解决方式,但是这至少提供了另一个看问题的角度,希望对大家有用。  


本文转载自Vimer的程序世界 [ http://www.vimer.cn ] 

原文链接地址: http://www.vimer.cn/2011/01/%e5%b7%a7%e7%94%a8%e5%ae%8f%e5%ae%9a%e4%b9%89%e6%9d%a5%e7%ae%80%e5%86%99%e4%bb%a3%e7%a0%81.html 

你可能感兴趣的:(C++)