GameAcademe

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  0 Posts :: 14 Stories :: 5 Comments :: 0 Trackbacks

常用链接

留言簿(5)

我参与的团队

搜索

  •  

最新评论

2004年写的老文章,从CSDN搬过来

ISO C++推出之后,C/C++中宏(macro)的使用一直都备受争议,就好像当年保守诟病的goto语句一样。有所不同的是,现在的C/C++代码中使用goto语句的使用率是越来越少了。而macro仍然在C/C++ programming中占据一席之地——例如集赞誉之耀和诋毁之辱于一身的Microsoft Foudation Classes就把macro的强大功能发挥得淋漓尽致。套用“存在着就是合理”,macro的存在必定有其合理的因素。事实上,如果在programming的时候充分发挥macro的机制,就能写出一些巧妙精致而且设计合理的代码。

我在工作中阅读了一个引擎的代码,引擎在某处就比较巧妙地利用了macro的功能。在此我将其整理出来
,供大家学习交流。

大家在进行C/C++ programming的时候,常常定义一些枚举类型的数据,例如:

1enum EMessage
2{
3   MSG_OPEN,
4   MSG_CLOSE,
5   MSG_COPY,
6   MSG_PASTE
7}
;


在某些时候,比如在调试某段程序的时候,使用调试器捕获了某个枚举变量的值,这时候我们所能得到的是一些数值。例如当变量EMessage eMsg = MSG_OPEN的时候,我们能观察到eMsg = 0。但是单单一个“0”的话一下子让人难以明白它的含义,如果想在屏幕上也能打印出枚举的名称就更加不好办了。

解决这个问题,方法之一,就是利用macro的强大灵活的机制。现在我们来一步一步地分析如何利用macro来解决上述的问题。

想打印枚举的名称,你首先想到的肯定是:使用一个字典数据结构记录枚举变量和描述字符串的映射关系。例如:

 1#include <map>
 2
 3using namespace std;
 4
 5map<EMessage,const char*> MsgDesc; //为了节省空间,不使用string存储描述信息
 6
 7MsgDesc[MSG_OPEN] = "MSG_OPEN";
 8MsgDesc[MSG_CLOSE] = "MSG_CLOSE";
 9MsgDesc[MSG_COPY] = "MSG_COPY";
10MsgDesc[MSG_PASTE] = "MSG_PASTE";

使用字典数据结构很方便,但是如果枚举值很少的时候,使用一个map类型的对象来管理这些东西似乎有点暴殄天物(或许对于现在的硬件设备而言不算什么,但是如果性能有着严格要求的话。。。)。如果枚举值很多的话,每添加一个新的枚举量就要在枚举定义内写一次,在把枚举量描述添加进字典中又要写一次,尤为繁琐。

如果使用macro机制的话,可以通过预编译和macro机制一次性处理上述的问题。

例如:在文件msgdef.h中

 1#ifndef _MSGDEF_H_
 2#define _MSGDEF_H_
 3#undef USEMACRO  
 4#if defined(INCLUDE_AS_ENUM) //判断预编译宏的设置情况,判断是转换成enum还是string
 5#define MSG_MACRO(msg)    msg,
 6#elif defined(INCLUDE_AS_STRING)
 7#define MSG_MACRO(msg)  #msg,  //不能遗忘“,”号
 8#else
 9#error To use this include file, first define either INCLUDE_AS_ENUM or INCLUDE_AS_STRING
10#endif//有新定义的message 枚举值的话,就只是需要在此添加
11MSG_MACRO(MSG_OPEN)
12MSG_MACRO(MSG_CLOSE)
13MSG_MACRO(MSG_COPY)
14MSG_MACRO(MSG_PASTE)
16#endif


而使用的时候,就要如此使用,例如在main.cpp中

 

 1//定义消息的描述数组
 2char MsgDesc[32][32=  //要预先估计msg的数量
 3{
 4#define INCLUDE_AS_STRING //要使用msgdef.h中所指定的两个宏中的一个,否则会编译出错
 5#include "msgdef.h"
 6#undef  INCLUDE_AS_STRING //要把它取消,以便可是设置成
 7}
;
 8
 9//定义消息的枚举类型
10enum EMessage
11{
12#define INCLUDE_AS_ENUM 
13#include "msgdef.h"                     
14#undef  INCLUDE_AS_ENUM
15}
;

这样,就可以使用枚举和描述它的字符串信息了。

posted on 2011-04-20 16:38 游戏研究院 阅读(330) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理