#在 C++ 中定义常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4103086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
#defining constants in C++
提问by James
In various C code, I see constants defined like this:
在各种 C 代码中,我看到常量定义如下:
#define T 100
Whereas in C++ examples, it is almost always:
而在 C++ 示例中,它几乎总是:
const int T = 100;
It is my understanding that in the first case, the preprocessor will replace every instance of T with 100. In the second example, T is actually stored in memory.
我的理解是,在第一种情况下,预处理器会将 T 的每个实例替换为 100。在第二个示例中,T 实际上存储在内存中。
Is it considered bad programming practice to #define constants in C++?
在 C++ 中 #define 常量被认为是不好的编程习惯吗?
回答by James McNellis
Is it considered bad programming practice to #define constants in C++?
在 C++ 中 #define 常量被认为是不好的编程习惯吗?
Yes, because all macros (which are what #define
s define) are in a single namespace and they take effect everywhere. Variables, including const
-qualified variables, can be encapsulated in classes and namespaces.
是的,因为所有宏(这是#define
s 定义的)都在一个命名空间中并且它们在任何地方都有效。变量,包括const
限定变量,可以封装在类和命名空间中。
Macros are used in C because in C, a const
-qualified variable is not actually a constant, it is just a variable that cannot be modified. A const
-qualified variable cannot appear in a constant expression, so it can't be used as an array size, for example.
在 C 中使用宏是因为在 C 中,const
限定变量实际上不是常量,它只是一个不能修改的变量。例如,一个const
-qualified 变量不能出现在常量表达式中,因此它不能用作数组大小。
In C++, a const
-qualified object that is initialized with a constant expression (like const int x = 5 * 2;
) isa constant and can be used in a constant expression, so you can and should use them.
在 C++ 中,const
用常量表达式(如const int x = 5 * 2;
)初始化的-qualified 对象是一个常量并且可以在常量表达式中使用,因此您可以并且应该使用它们。
回答by paxdiablo
There is no requirement that T
be stored "in memory" in the second case, unless you do something like take the address of it. This is true of all variables.
T
在第二种情况下,没有要求将其存储在“内存中”,除非您执行诸如获取它的地址之类的操作。所有变量都是如此。
The reason the second one is better is that the first will frequently "disappear" in the pre-processor phase so that the compiler phase never sees it (and hence doesn't give it to you in debug information). But that behaviour is not mandated by the standard, rather it's common practice.
第二个更好的原因是第一个会经常在预处理器阶段“消失”,因此编译器阶段永远不会看到它(因此不会在调试信息中提供给您)。但是这种行为不是标准所要求的,而是一种常见的做法。
There's little need to use #define
statements any more other than for conditional compilation. Single constants can be done with const
, multiple related constants can be done with enum
and macros can be replaced with inline
functions.
#define
除了用于条件编译之外,几乎不需要使用语句。单个常量可以用 来完成const
,多个相关的常量可以用 来完成,enum
宏可以用inline
函数来代替。
回答by AnT
Due to the differences between the concepts of constantin C and C++, in C we are basically forced to use #define
(or enum
) most of the time. const
just doesn't work in C in most cases.
由于C 和 C++中常量概念的不同,在 C 中我们基本上大部分时间都被迫使用#define
(或enum
)。const
只是在大多数情况下在 C 中不起作用。
But in C++ there's no such problem, so it is indeed bad practice to rely on #define
d constants in C++ (unless you really need a textually-substituted constant for some reason).
但是在 C++ 中没有这样的问题,所以#define
在 C++ 中依赖d 常量确实是不好的做法(除非出于某种原因你真的需要一个文本替换的常量)。
回答by EboMike
Yes. At the very least, use enums. Both const int
and enum
s will be evaluated at compile-time, so you have the same performance. However, it's much cleaner, will be easier to debug (the debugger will actually know what T is), it's type-safe, and less likely to break in complex expressions.
是的。至少,使用枚举。无论const int
和enum
旨意在编译时计算,所以你有同样的表现。然而,它更简洁,更容易调试(调试器实际上知道 T 是什么),它是类型安全的,并且不太可能在复杂的表达式中中断。
回答by Nikolai Fetissov
Preprocessor macros do not respect the scope- it's a simple text substitution - while static const int blah = 1;
can be enclosed in a namespace. The compiler will still optimize both cases (unless you take address of that variable) but it's type- and scope-safe.
预处理器宏不考虑范围- 它是一个简单的文本替换 - 而static const int blah = 1;
可以包含在命名空间中。编译器仍会优化这两种情况(除非您获取该变量的地址),但它是类型和范围安全的。
回答by Chris W.
Yes. The biggest reason is that preprocessor definitions do not obey the scoping rules of the language, polluting the global namespace, and worse -- they're even replaced in cases like
是的。最大的原因是预处理器定义不遵守语言的范围规则,污染全局命名空间,更糟糕的是——它们甚至在以下情况下被替换
x->sameNameAsPreprocessorToken
Since preprocessor definitions are replaced at the textual level, other normal properties of variables do not apply - you can take the address of an int const, but not of a #define'd constant.
由于预处理器定义在文本级别被替换,变量的其他正常属性不适用 - 您可以获取 int const 的地址,但不能获取 #define'd 常量的地址。
As noted by others, you also typically lose type safety and debugging ability.
正如其他人所指出的,您通常也会失去类型安全和调试能力。
回答by Michael Goldshteyn
One other cool point is that global integral constants could be optimized out by the compiler so that they do not take up any space (i.e., memory). Therefore, they can be treated as literal constants when they are used and be as optimal as #define
based constants, without all of the pre-processor issues.
另一个很酷的一点是编译器可以优化全局整数常量,这样它们就不会占用任何空间(即内存)。因此,它们在使用时可以被视为文字常量,并且与#define
基于常量一样最佳,而没有所有预处理器问题。