尽量避免写重复代码;我使用宏来将方法分成一个类。
我想在头文件中定义一个宏函数,如:
cracker.h
#include<message.h>
class Cracker {
#define DECLARE_MSG(MSG_NAME, MSG_TYPE,ALREADY_DEFINED) \
{ \
if(!ALREADY_DEFINED)
{ \
virtual bool cbProcessMsg_##MSG_NAME (API::MSG_NAME##Msg const & msg); \
}\
#include "message.h"
#undef DECLARE_MSG
};
message.h
DECLARE_MSG(AddOrder , 'A', false);
DECLARE_MSG(DeleteOrder , 'B', true);
DECLARE_MSG(ReplaceOrder , 'C', false);
...
但是这段代码注意到编译,因为我无权在函数外添加if语句。
还有其他选择吗?
答案 0 :(得分:2)
有几个值得强调的项目:
1。 宏不知道范围;你可以删除它的唯一方法就是取消定义它。
2。 宏按原样粘贴到代码中;然后编译。宏本身不是一个函数,它是一个代码生成工具。这意味着即使'ALREADY_DEFINED'为真,您也会得到另一个定义。
3。 你要做的是在类定义之外的类中添加一个函数。你不能这样做。如初。
4。 头部防护装置将为您节省大中型项目的痛苦;你应该早点进入使用它们的习惯。
虽然不完全相同,但您想要做的是查看工厂模式。
答案 1 :(得分:0)
如果您(可以)使用boost-library,请使用BOOST_PP_IIF
:
#define DECLARE_MSG(MSG_NAME, MSG_TYPE,ALREADY_DEFINED) \
BOOST_PP_IIF(ALREADY_DEFINED,, \
virtual bool cbProcessMsg_##MSG_NAME (API::MSG_NAME##Msg const & msg); \
)
您应该使用0
和1
代替false
和true
。
但是如果你不这样做,你可以通过将名称和数字连接到另一个宏来“分支”定义:
// two definitions for PP_CONCAT to expand macros, etc...
#define PP__CONCAT(a, b) a ## b
#define PP_CONCAT(a, b) PP__CONCAT(a, b)
// to expand your macro you should pass it through another macro
#define PP_EXPAND(...) __VA_ARGS__
#define DECLARE_MESSAGE_0(MSG_NAME, MSG_TYPE) /** the def when ALREADY_DEFINED = 0 */
#define DECLARE_MESSAGE_1(MSG_NAME, MSG_TYPE) /** the other branch */
#define DECLARE_MESSAGE(MSG_NAME, MSG_TYPE, ALREADY_DEFINED) \
PP_EXPAND(PP_CONCAT(DECLARE_MESSAGE_, ALREADY_DEFINED)(MSG_NAME, MSG_TYPE))
如果您在理解预处理器时遇到问题,则应使用选项-E /检查输出,并使用命令cpp
运行代码(代表 c - p re p rogressor和不 c p lus p lus ( - &GT; c++
))
然而,使用模板和继承可能还有另一种方法可以做同样的事情......