static const vs #define

时间:2009-10-28 13:44:28

标签: c++ c const

使用static const vars比#define预处理器更好吗?或者可能取决于具体情况?

每种方法的优点/缺点是什么?

11 个答案:

答案 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)

  • 输入一个静态const(它有一个类型),编译器可以检查它是否有效,重新定义等。
  • #define可以被重新定义为undefined。

通常你应该更喜欢静态的。它没有缺点。 prprocessor应主要用于条件编译(有时可能用于非常脏的trics)。

答案 5 :(得分:2)

请参见此处:static const vs define

通常是一个const声明(注意它不需要是静态的)是要走的路

答案 6 :(得分:2)

不建议使用预处理程序指令#define定义常量,不仅适用于C++,还适用于C。这些常量不具有该类型。即使在C中,也建议将const用于常量。

答案 7 :(得分:1)

总是喜欢使用语言功能而不是预处理器等其他工具。

  

ES.31:不要将宏用于常量或"功能"

     

宏是bug的主要来源。宏不遵守通常的范围   并键入规则。宏不遵守通常的论证规则   通过。宏确保人类读者看到不同的东西   从编译器看到的。宏使工具构建复杂化。

来自C++ Core Guidelines

答案 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成员变量)。