在C ++中定义全局常量

我想在C ++中定义一个常量在几个源文件中可见。 我可以通过以下几种方法在头文件中定义它:

  1. #define GLOBAL_CONST_VAR 0xFF
  2. int GLOBAL_CONST_VAR = 0xFF;
  3. 一些函数返回值(例如int get_GLOBAL_CONST_VAR()
  4. enum { GLOBAL_CONST_VAR = 0xFF; }
  5. const int GLOBAL_CONST_VAR = 0xFF;
  6. extern const int GLOBAL_CONST_VAR; 并在一个源文件中const int GLOBAL_CONST_VAR = 0xFF;

选项(1) – 绝对不是你想使用的选项

选项(2) – 使用头文件在每个目标文件中定义variables的实例

选项(3) – 在大多数情况下,国际海事组织过度杀人

选项(4) – 在许多情况下可能不好,因为枚举没有具体types(C ++ 0X将增加定义types的可能性)

所以在大多数情况下,我需要在(5)和(6)之间进行select。 我的问题:

  1. 你喜欢什么(5)或(6)?
  2. 为什么(5)是好的,而(2)不是?

(5)确切地说你想说什么。 另外,它可以让编译器在大部分时间内优化它。 (6)另一方面不会让编译器优化它,因为编译器不知道你是否会最终改变它。

肯定会用选项5 – 它是types安全的,并允许编译器优化(不考虑该variables的地址:)另外,如果它在一个标题 – 将其粘贴到一个名称空间,以避免污染全局范围:

 // header.hpp namespace constants { const int GLOBAL_CONST_VAR = 0xFF; // ... other related constants } // namespace constants // source.cpp - use it #include <header.hpp> int value = constants::GLOBAL_CONST_VAR; 

(5)比(6)更好,因为它将GLOBAL_CONST_VAR定义为所有翻译单元中的整数常量expression式(ICE)。 例如,您可以在所有翻译单元中将其用作数组大小和案例标签。 在(6)的情况下, GLOBAL_CONST_VAR将只在定义点的翻译单元中成为ICE。 在其他翻译单位,它不会像ICE一样工作。

但是请记住,(5)给出了GLOBAL_CONST_VAR内部链接,这意味着GLOBAL_CONST_VAR的“地址标识”在每个翻译单元中将会不同,也就是说,在每个翻译单元中, &GLOBAL_CONST_VAR会给你一个不同的指针值。 在大多数使用情况下,这并不重要,但是如果您需要一个具有一致的全局“地址标识”的常量对象,则必须使用(6),牺牲常量的ICE性处理。

另外,当常量的ICE性不是一个问题(不是一个整数types),而且types的大小变大(不是一个标量types),那么(6)通常会比(5)更好。

(2)不正确,因为(2)中的GLOBAL_CONST_VAR默认有外部链接。 如果你把它放在头文件中,你通常会得到GLOBAL_CONST_VAR多个定义,这是一个错误。 C ++中的const对象默认具有内部链接,这就是为什么(5)起作用的原因(正如我上面所说,这是为什么每个翻译单元都有独立的GLOBAL_CONST_VAR )。

如果这将是一个常数,那么你应该把它作为一个常数 – 这就是为什么2在我看来是不好的。

编译器可以使用该值的常量性质来扩展一些math,甚至可以使用其他值。

5和6之间的select – 5对我来说感觉更好。

6)价值是不必要地从它的声明分离。

我通常会有一个或多个这些头文件,它们只在其中定义常量等,然后没有其他“聪明”的东西 – 很好的轻量级头文件,可以很容易地被包含在任何地方。

 const int GLOBAL_CONST_VAR = 0xFF; 

因为这是一个常数!

要回答你的第二个问题:

(2)违反“一个定义规则”是非法的。 它在包含它的每个文件中定义GLOBAL_CONST_VAR ,即不止一次。 (5)是合法的,因为它不受“一个定义规则”的约束。 每个GLOBAL_CONST_VAR都是一个单独的定义,它包含在本地。 所有这些定义当然有相同的名称和价值,但是他们的地址可能不同。

 #define GLOBAL_CONST_VAR 0xFF // this is C code not C++ int GLOBAL_CONST_VAR = 0xFF; // it is not constant and maybe not compilled Some function returing the value (eg int get_LOBAL_CONST_VAR()) // maybe but exists better desision enum { LOBAL_CONST_VAR = 0xFF; } // not needed, endeed, for only one constant (enum elms is a simple int, but with secial enumeration) const int GLOBAL_CONST_VAR = 0xFF; // it is the best extern const int GLOBAL_CONST_VAR; //some compiller doesn't understand this 

这取决于你的要求。 (5)对于大多数正常使用来说是最好的,但是经常会导致每个目标文件中不断占用存储空间。 (6)在重要的情况下可以解决这个问题。

(4)如果你的优先级是保证存储空间不被分配的话,它也是一个不错的select,但是它当然只适用于积分常数。