2010-09-30 28 views
1

可能重复:
static const vs #define在整个应用程序中使用常量。使用的#define或可变

您好所有,在C++中,定义整个应用程序中使用的常数,你是什么人通常的做法?

#define WINDOWS_HEIGHT 1024 

const int WINDOWS_HEIGHT = 1024; 

感谢。

+1

调试器将无法对宏执行任何操作。 – 2010-09-30 03:34:27

+2

@Martin,这不一定是真的。 gdb支持[宏扩展](http://www.delorie。COM/GNU /文档/ GDB/gdb_70.html)。 – 2010-09-30 03:37:41

+2

参见[ static const vs #define ](http://stackoverflow.com/questions/1637332/static-const-vs-define)。 – 2010-09-30 03:41:08

回答

7

利弊一切,取决于用途:

  • 枚举
    • 唯一可能的整数值很好地处理
    • 强类型
    • 正常范围的/标识符冲突的问题,但是到了足够大的带符号或无符号整数大小,您无法控制(在C++ 03中)
    • 不能接收地址
    • 更强的使用限制(例如递增 - template <typename T> void f(T t) { cout << ++t; }将不会编译)
    • 每个常量的类型取自封闭的枚举,因此template <typename T> void f(T)从不同的枚举中传递相同的数值时会得到不同的实例化,所有这些都与任何实际的f(int)实例不同。
    • 即使使用typeof,也不能期望numeric_limits提供有用的洞察
    • 枚举的类型名可能出现在RTTI,编译器消息等的不同位置。 - 可能是有用的,可能混淆
  • consts很好
  • 强,单一的,用户指定的类型
  • 一个定义规则并发症
  • 定义处理
    • 正确作用域/标识符冲突问题
      • “全局”范围/更容易出现冲突的用法,这可能会产生难以解决的编译问题和意外的运行时结果,而不是理智的错误消息;减轻这一要求:
        • 长,模糊的和/或集中协调标识符,并获得他们不能从隐含受益匹配中/电流/凯尼格-查到的命名空间,命名空间别名等
        • 使用所有的大写字母通常是必需的,并且保留用于预处理器定义(企业级预处理器使用保持可管理的重要准则,以及可以期待遵循哪些第三方库),观察其中意味着现有常量或枚举的迁移定义涉及变化在大写(因此影响客户端代码)。 (就个人而言,我利用枚举的第一个字母,但不consts,所以我会在这里反正被击中 - 也许时间来重新考虑。)
      • 更多的编译时间操作成为可能:字符串字面串联,字串(以其大小)
        • 不足之处是给出#define X "x"和一些客户使用阿拉"pre" X "post",你就麻烦了,如果你想要或需要做X运行时可改变的变量,而不是一个常数,而这种转变是从const char*容易或const std::string,因为它们已经强制用户并入级联操作。
      • 不能使用sizeof直接在所定义的数值常数
      • 无类型(GCC不警告如果与无符号)
      • 一些编译器/链接器/调试器链可以不存在,则识别符,所以你将被缩减为查看“幻数”(字符串,无论...)
      • 不能接受地址
      • 在#define为上下文的上下文中,替换值不需要是合法的(或离散的)创建,因为它在每个使用点进行评估,因此您可以引用未声明的对象,取决于“实现” “T被预先包括,创建可用于初始化数组‘常量’如{ 1, 2 },或#define MICROSECONDS *1E-6等(绝对不推荐这个!)
      • __FILE____LINE__一些特殊的东西可以掺入宏替换

    作为一般规则,我用consts并考虑将其用于一般用途最专业的选择(尽管该有的都有了一个简单呼吁这个老懒惰的程序员)。

  • 2

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

    8

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

    +0

    除了连接问题外,访问速度应该更快,并且在某些情况下可以给编译器提供一些有用的提示:'如果some_const'恰好为0,'x^= some_const;'将不会产生任何代码。 – ruslik 2010-09-30 03:36:36

    +0

    enumerator是它的大小是实现定义的。不知道这是在C++中更改0x – Chubsdad 2010-09-30 04:00:03

    +0

    @Chubsdad:在C++中,您可以通过指定初始值设定项来控制枚举类型。在C中,类型是'int'。 – 2010-09-30 04:20:39

    3

    嗯,取决于。对于整型常量enum效果很好。例如:

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

    使用常量整数;它将显示在调试器中#define值可能不存在的地方。或者使用枚举;那也可以。

    2

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

    1

    使用define可以简单地用您的代码替换所有出现的值。常量全局变量几乎相同,只有类型可以明确定义。这几乎是唯一的区别。

    就我个人而言,我宁愿使用一个定义,只是出于品味。

    但是,我认为没有什么区别。

    相关问题