使用static const
vars比#define
预处理器更好吗?或者可能取决于具体情况?
每种方法的优点/缺点是什么?
答案 0 :(得分:221)
答案 1 :(得分:128)
就个人而言,我讨厌预处理器,所以我总是选择const。
#define的主要优点是它不需要存储在程序中的内存,因为它实际上只是用文字值替换了一些文本。它还具有没有类型的优点,因此它可以用于任何整数值而不会产生警告。
“const”的优点是它们可以作用域,并且可以在需要传递指向对象的指针的情况下使用它们。
我不知道你对“静态”部分到底发生了什么。如果你在全局声明,我会把它放在一个自治命名空间而不是静态。例如
namespace {
unsigned const seconds_per_minute = 60;
};
int main (int argc; char *argv[]) {
...
}
答案 2 :(得分:42)
如果这是一个C ++问题并且它提到#define
作为替代,那么它是关于“全局”(即文件范围)常量,而不是关于类成员。当谈到C ++中的这些常量static const
是多余的。在C ++中,const
默认情况下具有内部链接,并且声明它们static
没有意义。所以它实际上是关于const
与#define
的关系。
最后,在C ++中const
更可取。至少因为这些常量是键入和作用域的。除了极少数例外,除了#define
之外,没有理由更喜欢const
。
字符串常量BTW是此类异常的一个示例。使用#define
d字符串常量,可以使用C / C ++编译器的编译时连接功能,如
#define OUT_NAME "output"
#define LOG_EXT ".log"
#define TEXT_EXT ".txt"
const char *const log_file_name = OUT_NAME LOG_EXT;
const char *const text_file_name = OUT_NAME TEXT_EXT;
P.S。同样,以防万一有人提到static const
作为#define
的替代,通常意味着他们在谈论C,而不是C ++。我想知道这个问题是否被正确标记了......
答案 3 :(得分:5)
使用静态const就像在代码中使用任何其他const变量一样。这意味着您可以在信息来自的任何地方进行跟踪,而不是在预编译过程中仅在代码中替换的#define。
您可能需要查看此问题的C ++ FAQ Lite: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7
答案 4 :(得分:4)
通常你应该更喜欢静态的。它没有缺点。 prprocessor应主要用于条件编译(有时可能用于非常脏的trics)。
答案 5 :(得分:2)
请参见此处:static const vs define
通常是一个const声明(注意它不需要是静态的)是要走的路
答案 6 :(得分:2)
不建议使用预处理程序指令#define
定义常量,不仅适用于C++
,还适用于C
。这些常量不具有该类型。即使在C
中,也建议将const
用于常量。
答案 7 :(得分:1)
总是喜欢使用语言功能而不是预处理器等其他工具。
ES.31:不要将宏用于常量或"功能"
宏是bug的主要来源。宏不遵守通常的范围 并键入规则。宏不遵守通常的论证规则 通过。宏确保人类读者看到不同的东西 从编译器看到的。宏使工具构建复杂化。
答案 8 :(得分:1)
#define
可能会导致意外结果:
#include <iostream>
#define x 500
#define y x + 5
int z = y * 2;
int main()
{
std::cout << "y is " << y;
std::cout << "\nz is " << z;
}
输出错误的结果:
y is 505
z is 510
但是,如果将其替换为常量:
#include <iostream>
const int x = 500;
const int y = x + 5;
int z = y * 2;
int main()
{
std::cout << "y is " << y;
std::cout << "\nz is " << z;
}
它输出正确的结果:
y is 505
z is 1010
这是因为#define
仅替换了文本。因为这样做会严重破坏操作顺序,所以我建议改用常量变量。
答案 9 :(得分:1)
作为一个相当老而生锈的C程序员,他从来没有完全使用C ++,因为出现了其他事情,并且现在正在努力掌握Arduino,我的观点很简单。
#define是编译器预处理程序指令,应按原样使用,用于条件编译等。低级代码需要定义一些可能的替代数据结构,以实现特定硬件的可移植性。根据模块的编译和链接顺序,它可能会产生不一致的结果。如果您需要在范围上具有全局性,请适当地进行定义。
const和(静态const)应始终用于命名静态值或字符串。它们是安全的类型,调试器可以完全使用它们。
枚举总是让我感到困惑,所以我设法避免了它们。
答案 10 :(得分:0)
如果要定义要在类的所有实例之间共享的常量,请使用static const。如果常量特定于每个实例,只需使用const(但请注意,类的所有构造函数都必须在初始化列表中初始化此const成员变量)。