Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是使用宏的好方法吗?_C++_Objective C_Language Agnostic_Macros_Styles - Fatal编程技术网

C++ 这是使用宏的好方法吗?

C++ 这是使用宏的好方法吗?,c++,objective-c,language-agnostic,macros,styles,C++,Objective C,Language Agnostic,Macros,Styles,我知道宏的重要性,当我真正想要的是函数时,我会避免使用宏 不过,我发现它们的用处在于存储“神奇”数字、文件名、字体名等。比如: ProjectHeader.h #ifndef __PROJECT_HEADER__ #define __PROJECT_HEADER__ #define kXMLFileName "scoresAndSettings.xml" #define AUDIO_DATA_TYPE_FORMAT SInt16 #define NUM_AUDIO_BUFFERS 3 #d

我知道宏的重要性,当我真正想要的是函数时,我会避免使用宏

不过,我发现它们的用处在于存储“神奇”数字、文件名、字体名等。比如:

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];
)。这使我能够直接开始测试我正在处理的项目的任何部分,只需操作
ProjectHeader.h
文件中的宏
#define
d即可


这个好吗?糟糕?下次有更好的方法吗?

首先,在您的第一组宏中,没有任何一个是不可用的 最好使用
const
变量,至少在C++中:

char const kXMLFileName[] = "socresAndSettings.xml";
typedef SInt16 audioDataTypeFormat;
int const numAudioBuffers = 3;
//  ...
使用
const
而不是宏的优点是名称将 服从范围;对于数值,您还可以 更容易指定类型(如果不是
int
)。如有误用,, 错误消息通常也更容易理解

对于你的第二个街区,很难说(但是你选择的名字) 导致未定义的行为)。我的印象是这些都是 用于有条件服从。如果是这样,那么它们必须是宏。但是 一般来说,条件编译是需要避免的,除非 你的目标是混淆

这并不是说你不应该使用宏。没有别的了 在日志记录中自动插入
\uuuuu文件\uuuuuu
\uuuu行\uuuuu
的方法 例如,原语。我还广泛使用了它们 与Python或其他定义C API的语言接口:在C语言中 API,“重载”是通过手动名称篡改和标记粘贴完成的
宏是实现这一点的唯一简单方法。

(顺便说一句,这是一个Objective-C++项目,但我认为从概念上讲,这个问题与语言无关。)@Adam Obj-C++是一个东西。这是一件疯狂而混乱的事情,但也被描述为“不可思议的强大”。我可能会一直使用它,直到有人付钱让我停止…我放弃。但是你的帖子似乎是这篇文章的翻版:你为什么不使用
const
s和
typedef
s呢?此外,那个些带有两个下划线的名称是保留的,它可能会编译得同样快。尽管处理是在不同的编译阶段完成的。但是,const/typedef方法是类型安全的,而宏则不是。调试也有一些好处(const有一个名称)。非常好的答案,谢谢!(你能解释一下为什么这些名称会导致未定义的行为吗?@buildsuccessed,因为标准是这样说的:-)(§17.4.3.1.2在C++03中):“每个包含双下划线(
\uuuu
)或以下划线开头,后跟大写字母的名称都为实现保留,以供任何使用。”对于违反此约束会发生什么,标准相当不明确,但传统上,它被认为是未定义的行为。