乐陵市职业中等专业学校

 简约管理制度,真情关爱入手,以人为本、以德立校、办人民满意的职业教育,育社会需要的时代英才。

     -----育人理念

                             
厚德 · 博学 · 精技 · 创新

校园新闻

Campus news

   
   
    
/
/
Crest的语法---宏的魔术汇演
来源: | 作者:pmoa3cb2c | 发布时间: 2009-12-03 | 1090 次浏览 | 分享到:
最理想的面向对象语法当然是仿造C#、java这样的结构了,但是因为C语言要用头文件,所以估计最终的样式还是类似于C++。首先我们还是制定一个目标的样式,然后再去用Crest仿造实现。目标是这样的[代码1]:

  class CString: CObject, IUnknown, IDispatch

  {

  int length;

  char * buffer;

  public virtual void Format(char * format)

  {

  DoFormat(format);

  }

  public void DoFormat(char * format)

  {

  if( OnFormat != null ) OnFormat(format);

  }

  public abstract void OnFormat(char * format);

  }

  要想用Crest实现上面的结构,有几个问题要注意:

  this指针。所有的对象成员定义和调用都隐含有一个this指针

  命名规范,CString的Format和CDateTime的Format肯定不是同一个东西,但是C语言不支持override,所以要保证成员函数不重名。

  经过两天的断断续续工作,最终呈现结果如下[代码2]:

  DECLARE_CLASS(CString)

  EXTENDS(CObject, IMPLEMENT2(IUnknown,IDispatch))

  DECLARE_FIELD(CString, int, length)

  DECLARE_FIELD(CString, char *, buffer)

  DECLARE_VIRTUAL1(CString, void, Format, const char * format)

  DECLARE_ABSTRACT1(CString, void, OnFormat,const char * format)

  DECLARE_METHOD1(CString, void, DoFormat,const char * format)

  DECLARE_CONSTRUCTOR(CString)

  DECLARE_DESTRUCTOR(CString)

  END_DECLARE(CString);

  这个风格是不是觉得有些累赘?bigtall开始也觉得不满意,但是后来发现借助C语言的Macro魔法,这样的结构反而是最简单的,或者说,比较爽!

  在最终演化到这个样子的代码风格之前,我们可以手工来实现一个不用macro的版本,有对比才有真相啊!我们还是参考(代码1)部分,根据我们上文得到的经验,可以很轻松把代码给出来[代码3]:

  struct Class_CString;

  typedef struct Class_CString CString;

  void CString_Format (CString *self, const char * format);

  void CString_OnFormat (CString *self, const char * format);

  void CString_DoFormat (CString *self, const char * format);

  void CString_constructor (CString *self);

  void CString_destructor (CString *self);

  struct Class_CString{

  int length;

  char * buffer;

  void (*Format) (CString *self, const char * format);

  void (*OnFormat) (CString *self, const char * format);

  };

  多了好多东西,写起来很麻烦,如果我们以后增加更多的特性的话,恐怕会成为噩梦。Crest要想让别人也去用,语法上面一定要让人觉得“合算”---增加一定的繁琐,但是得到的有用特性更多。为了实现(代码2)到(代码3)的转换,我们来看一下实际(代码2)的头文件定义:

  /* filename: macropure.h */

  #if defined(DECLARATION) || defined(DEFINITION)

  #include "CrestMacro.h"

  DECLARE_CLASS(CString)

  ./main/20081289304942/Page/*此处省略*/

  END_DECLARE(CString);

  #else

  #define DECLARATION

  #include "macropure.h"

  #undef DECLARATION

  #define DEFINITION

  #include "macropure.h"

  #undef DEFINITION

  #endif