这是使用宏的好方法吗?

时间:2012-05-28 11:46:14

标签: c++ objective-c language-agnostic macros styles

我知道pitfalls的宏,并在我真正想要的是一个函数时避免它们。

我发现它们有用的是存储“魔术”数字,文件名,字体名称等内容。所以像:

ProjectHeader.h

#ifndef __PROJECT_HEADER__
#define __PROJECT_HEADER__

#define kXMLFileName "scoresAndSettings.xml"

#define AUDIO_DATA_TYPE_FORMAT SInt16
#define NUM_AUDIO_BUFFERS 3
#define AUDIO_SAMPLE_RATE 44100.
#define NUM_AUDIO_CHANNELS 2

#define kGameFont @"Helvetica-Bold"
#define kGameFontSizeNormal 18
#define kGameFontSizeSmall 16
#define kGameFontSizeTiny 11

这些让我(a)将UI细节存储在一个我可以更改它们的地方,并知道更改将在整个代码中传播,(b)给它们一个名称来描述它们在代码中的功能,以及(c)使用代码自动完成,知道我实际上输入了正确的术语。

我相信这不是一种可怕的工作方式,但我想知道是否有人认为是这样,如果是的话,如何做得更好。

这些可能有些笨拙,但我仍然觉得它们非常有用:

#define __COPY_PROTECTION__
#define __SHOW_FPS__ NO
#define __SKIP_LAUNCH_SCREEN__ 0
#define __START_IN_GAMEPLAY__ 1
#define __START_IN_PREFS__ 0
#define __START_IN_WIN_SCENE__ 0
#define __AUTO_WIN_TESTING__ 0

(在各个方面,然后在代码中:

AppDelegate.h
if (__START_IN_GAMEPLAY__) {
 [self show:MyGameplay];
 return;
}
[self show:MainScreen];

)。这使我可以直接测试我正在处理的项目的任何部分,只需操作#define文件中的宏ProjectHeader.h d。

这是好事吗?坏?下次还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

首先,你的第一组宏中没有任何内容 最好用const变量来完成,至少在C ++中是这样的:

char const kXMLFileName[] = "socresAndSettings.xml";
typedef SInt16 audioDataTypeFormat;
int const numAudioBuffers = 3;
//  ...

使用const代替宏的优点是名称会 服从范围;对于数值,您也可以享受优势 更容易指定类型(如果它不是int)。如果误用, 错误消息通常也更容易理解。

对于你的第二个区块,它更难说(但你选择的名字 导致未定义的行为)。我的印象是这些都是 用于条件恭维。如果是这样,那么它们必须是宏。但 通常,条件编译是可以避免的,除非 你的目标是混淆。

这并不是说你永远不应该使用宏。没有其他的 在日志记录中自动插入__FILE____LINE__的方法 例如,原语。我还广泛使用它们 连接到Python或定义C API的其他语言:在C中 API,“重载”是通过手动名称修改和标记粘贴来完成的 宏是实现这一目标的唯一简单方法。