#defining C ++中的常量

时间:2010-11-05 02:16:04

标签: c++

在各种C代码中,我看到如下定义的常量:

#define T 100

在C ++示例中,它几乎总是:

const int T = 100;

据我所知,在第一种情况下,预处理器将用100替换T的每个实例。在第二个例子中,T实际上存储在内存中。

在C ++中#define常量被认为是不好的编程习惯吗?

7 个答案:

答案 0 :(得分:34)

  

在C ++中#define常量被认为是不好的编程习惯吗?

是的,因为所有的宏(#define定义的)都在一个命名空间中,它们在任何地方生效。变量,包括const - 限定变量,可以封装在类和名称空间中。

宏在C中使用,因为在C中,const - 限定变量实际上不是常量,它只是一个无法修改的变量。 const - 限定变量不能出现在常量表达式中,因此不能将其用作数组大小。例如。

在C ++中,使用常量表达式初始化的const限定对象(如const int x = 5 * 2;常量,可用于常量表达式,因此你可以而且应该使用它们。

答案 1 :(得分:7)

在第二种情况下,不要求T存储在“内存中”,除非你做了类似的地址。所有变量都是如此。

第二个更好的原因是第一个会在预处理器阶段经常“消失”,因此编译器阶段永远不会看到它(因此在调试信息中不会给你)。但这种行为并非标准规定,而是通常的做法。

除了条件编译之外,几乎不需要使用#define语句。单个常量可以使用const完成,多个相关常量可以使用enum完成,宏可以替换为inline个函数。

答案 2 :(得分:3)

由于C和C ++中常量的概念之间的差异,在C中我们基本上被迫在大多数时间使用#define(或enum)。在大多数情况下,const在C中不起作用。

但是在C ++中没有这样的问题,所以在C ++中依赖#define d常量确实是不好的做法(除非你出于某种原因确实需要一个文本替换的常量)。

答案 3 :(得分:2)

是。至少,使用枚举。 const intenum都将在编译时进行评估,因此您具有相同的性能。但是,它更干净,调试更容易(调试器实际上会知道T是什么),它是类型安全的,并且不太可能在复杂表达式中断。

答案 4 :(得分:1)

预处理器宏不尊重范围 - 它是一个简单的文本替换 - 而static const int blah = 1;可以包含在命名空间中。编译器仍将优化这两种情况(除非你获取该变量的地址),但它的类型和范围安全。

答案 5 :(得分:1)

是。最大的原因是预处理器定义不遵守语言的范围规则,污染全局命名空间,更糟糕的是 - 它们甚至在像

这样的情况下被替换。
x->sameNameAsPreprocessorToken

由于预处理器定义在文本级别被替换,因此变量的其他常规属性不适用 - 您可以获取int const的地址,但不能获取#define'd常量的地址。

正如其他人所说,您通常也会失去类型安全和调试能力。

答案 6 :(得分:0)

另一个很酷的观点是,编译器可以优化全局积分常数,使它们不占用任何空间(即内存)。因此,它们在使用时可以被视为文字常量,并且与基于#define的常量一样最优,而不会出现所有预处理器问题。