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

时间:2010-09-30 03:22:59

标签: c++

  

可能重复:
  static const vs #define

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

#define WINDOWS_HEIGHT 1024

const int WINDOWS_HEIGHT = 1024;

感谢。

7 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分: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或定义的枚举涉及大写的变化(因此影响客户代码)。 (就我个人而言,我将枚举的第一个字母大写,但不是有效的,所以无论如何我都会被打到这里 - 也许是时候重新考虑一下了。)
    • 更多可能的编译时操作:字符串文字串联,字符串化(取其大小)
      • 缺点是给定#define X "x"和一些客户端使用ala "pre" X "post",如果你想要或需要使X成为运行时可更改的变量而不是常量,那么你会遇到麻烦,而那个过渡是更容易从const char*const std::string,因为他们已经强制用户合并连接操作。
    • 不能直接在已定义的数字常量上使用sizeof
    • 无类型(如果与无符号相比,GCC不会发出警告)
    • 某些编译器/链接器/调试器链可能不会显示标识符,因此您将被缩减为查看“魔术数字”(字符串,等等......)
    • 无法取得地址
    • 在创建#define的上下文中,替换值不一定合法(或离散),因为它在每个使用点进行评估,因此您可以引用尚未声明的对象,取决于“实现”不需要预先包含,创建“常量”,如{ 1, 2 }可用于初始化数组,或#define MICROSECONDS *1E-6等(绝对不推荐这个!)< / LI>
    • __FILE____LINE__等特殊内容可以合并到宏替换

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

答案 2 :(得分:3)

嗯,取决于。对于整数常量enum效果很好。类似的东西:

struct Constants {
    enum {
        WindowHeight = 8,
        WindowWidth  = 8,
        // ...
    };
};
...
int h = Constants::WindowHeight;

答案 3 :(得分:3)

使用常数整数;它将显示在调试器中,#define值可能不会。或使用枚举;这也有效。

答案 4 :(得分:2)

我的投票是在一个只有一个翻译单元中定义的'namespace scope extern const'变量。命名空间范围'const'变量具有内部链接。

答案 5 :(得分:2)

我使用命名空间范围extern const。

答案 6 :(得分:1)

使用define只需用该值替换代码中的所有实例。 const全局变量几乎相同,只能显式定义类型。这几乎是唯一的区别。

就个人而言,我更喜欢使用定义,只是出于品味。

但是,我认为没有任何区别。