在整个应用程序中使用常量.使用#define或变量

Che*_*eng 1 c++

可能重复:
static const vs #define

大家好,在C++中,要定义一个在整个应用程序中使用的常量,你们通常的做法是什么?

#define WINDOWS_HEIGHT 1024
Run Code Online (Sandbox Code Playgroud)

要么

const int WINDOWS_HEIGHT = 1024;
Run Code Online (Sandbox Code Playgroud)

谢谢.

Aru*_*run 8

如何使用enum而不是担心链接?

  • @Michael:"在C++中,你可以通过指定一个初始化器来控制枚举类型".那会是什么样的?我认为你可能会通过包含一个负值来影响符号,或者知道跨越枚举所需的最小大小,但是你不能使用超过你想要的任意数量来阻止它,或者强迫它使用一个小范围的无符号类型. .?(我知道你可以探测你的编译器的行为并推断出一些特定于实现的hackery.) (2认同)

Ton*_*roy 7

一切的利弊,取决于用法:

  • 枚举
    • 仅适用于整数值
    • 正确处理范围/标识符冲突问题处理得很好
    • 强类型,但是一个足够大的有符号或无符号的int大小,你无法控制(在C++ 03中)
    • 不能拿地址
    • 更强的使用限制(例如递增 - template <typename T> void f(T t) { cout << ++t; }不会编译)
    • 每个常量的类型取自封闭的枚举,因此template <typename T> void f(T)当从不同的枚举中传递相同的数值时,获得一个独特的实例化,所有这些都与任何实际的f(int)实例化不同.
    • 即使使用typeof,也不能指望numeric_limits提供有用的洞察力
    • enum的typename可能出现在RTTI,编译器消息等各个地方 - 可能有用,可能是混淆
  • consts
    • 正确处理范围/标识符冲突问题处理得很好
    • 强大的,单一的,用户指定的类型
    • 一个定义规则并发症
  • 定义
    • "全局"范围/更容易出现冲突的用法,这会产生难以解决的编译问题和意外的运行时结果,而不是明智的错误消息; 减轻这种情况需要:
      • 长,模糊和/或集中协调的标识符,对它们的访问不能从隐式匹配used/current/Koenig-looking-up命名空间,命名空间别名等中受益.
      • 通常需要使用所有大写字符并为预处理器定义保留(企业规模预处理器使用以保持可管理的重要指南,以及可以预期哪些第三方库可以遵循),观察这意味着将现有的consts或enums迁移到定义涉及资本化的变化(因此影响客户代码).(就我个人而言,我将枚举的第一个字母大写但不是有效的,所以无论如何我都会被打到这里 - 也许是时候重新考虑一下了.)
    • 可能的更多编译时操作:字符串文字串联,字符串化(取其大小)
      • 缺点是给定#define X "x"和一些客户端使用ala "pre" X "post",如果你想要或者需要使X成为运行时可更改的变量而不是常量,那么你会遇到麻烦,而这种转换更容易从a const char*或者const std::string它们已经迫使用户加入连接操作.
    • 不能直接在定义的数字常量上使用sizeof
    • 无类型(如果与无符号相比,GCC不会发出警告)
    • 某些编译器/链接器/调试器链可能不会显示标识符,因此您将被简化为查看"魔术数字"(字符串,无论......)
    • 不能拿地址
    • 在创建#define的上下文中,替换值不一定是合法的(或离散的),因为它在每个使用点进行评估,因此您可以引用尚未声明的对象,依赖于不需要的"实现"预先包含,创建"常量",如{ 1, 2 }可用于初始化数组,或#define MICROSECONDS *1E-6等等.(绝对不推荐这个!)
    • 一些特殊的东西__FILE__,__LINE__可以并入宏观替代

作为一般规则,我使用consts并认为它们是一般用法的最专业选项(尽管其他人对这个老懒惰的程序员有一个简单的吸引力).