在 C++ 头文件中定义常量变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12042549/
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
Define constant variables in C++ header
提问by bames53
A program I am working on has many constants that apply throughout all classes. I want to make one header file "Constants.h", and be able to declare all the relevant constants. Then in my other classes, I can just include #include "Constants.h
.
我正在开发的一个程序有许多适用于所有类的常量。我想制作一个头文件“Constants.h”,并且能够声明所有相关的常量。然后在我的其他课程中,我可以只包含#include "Constants.h
.
I got it to work fine using #ifndef
... #define ...
syntax. However, I would prefer to use the const int...
form of constants. I'm not quite sure how to though.
我使用#ifndef
...#define ...
语法让它正常工作。但是,我更愿意使用const int...
常量的形式。我不太确定该怎么做。
回答by bames53
You could simply define a series of const ints
in a header file:
您可以简单地const ints
在头文件中定义一系列:
// Constants.h
#if !defined(MYLIB_CONSTANTS_H)
#define MYLIB_CONSTANTS_H 1
const int a = 100;
const int b = 0x7f;
#endif
This works because in C++ a name at namespace scope (including the global namespace) that is explicitly declared const and not explicitly declared extern has internal linkage, so these variables would not cause duplicate symbols when you link together translation units. Alternatively you could explicitly declare the constants as static.
这是有效的,因为在 C++ 中,在命名空间范围(包括全局命名空间)中显式声明为 const 而未显式声明为 extern 的名称具有内部链接,因此当您将翻译单元链接在一起时,这些变量不会导致重复符号。或者,您可以将常量显式声明为静态。
static const int a = 100;
static const int b = 0x7f;
This is more compatible with C and more readable for people that may not be familiar with C++ linkage rules.
这与 C 更兼容,对于可能不熟悉 C++ 链接规则的人来说更具可读性。
If all the constants are ints then another method you could use is to declare the identifiers as enums.
如果所有常量都是整数,那么您可以使用的另一种方法是将标识符声明为枚举。
enum mylib_constants {
a = 100;
b = 0x7f;
};
All of these methods use only a header and allow the declared names to be used as compile time constants. Using extern const int
and a separate implementation file prevents the names from being used as compile time constants.
所有这些方法都只使用一个头文件,并允许将声明的名称用作编译时常量。使用extern const int
和 单独的实现文件可防止名称用作编译时常量。
Note that the rule that makes certain constants implicitly internal linkage doesapply to pointers, exactly like constants of other types. The tricky thing though is that marking a pointer as const
requires syntax a little different that most people use to make variables of other types const. You need to do:
请注意,使某些常量隐式内部链接的规则确实适用于指针,就像其他类型的常量一样。但棘手的是,将指针标记为const
需要的语法与大多数人用来使其他类型的变量为 const 的语法略有不同。你需要做:
int * const ptr;
to make a constant pointer, so that the rule will apply to it.
制作一个常量指针,以便规则适用于它。
Also note that this is one reason I prefer to consistently put const
after the type: int const
instead of const int
. I also put the *
next to the variable: i.e. int *ptr;
instead of int* ptr;
.
另请注意,这是我更喜欢始终将const
类型放在后面的原因之一:int const
而不是const int
. 我也把*
旁边的变量: ieint *ptr;
而不是int* ptr;
.
I like to do these sorts of things because they reflect the general case of how C++ really works. The alternatives (const int
, int* p
) are just special cased to make some simple things more readable. The problem is that when you step out of those simple cases, the special cased alternatives become actively misleading.
我喜欢做这些事情,因为它们反映了 C++ 真正工作的一般情况。替代项 ( const int
, int* p
) 只是特殊情况,以使一些简单的事情更具可读性。问题在于,当您跳出这些简单的案例时,特殊案例的替代方案就会变得具有误导性。
So although the earlier examples show the common usage of const
, I would actually recommend people write them like this:
因此,尽管前面的示例显示了 的常见用法const
,但我实际上建议人们这样编写它们:
int const a = 100;
int const b = 0x7f;
and
和
static int const a = 100;
static int const b = 0x7f;
回答by Manikandaraj Srinivasan
I like the namespacebetter for this kind of purpose.
我更喜欢命名空间用于这种目的。
Option 1 :
选项1 :
#ifndef MYLIB_CONSTANTS_H
#define MYLIB_CONSTANTS_H
// File Name : LibConstants.hpp Purpose : Global Constants for Lib Utils
namespace LibConstants
{
const int CurlTimeOut = 0xFF; // Just some example
...
}
#endif
// source.cpp
#include <LibConstants.hpp>
int value = LibConstants::CurlTimeOut;
Option 2 :
选项2:
#ifndef MYLIB_CONSTANTS_H
#define MYLIB_CONSTANTS_H
// File Name : LibConstants.hpp Purpose : Global Constants for Lib Utils
namespace CurlConstants
{
const int CurlTimeOut = 0xFF; // Just some example
...
}
namespace MySQLConstants
{
const int DBPoolSize = 0xFF; // Just some example
...
}
#endif
// source.cpp
#include <LibConstants.hpp>
int value = CurlConstants::CurlTimeOut;
int val2 = MySQLConstants::DBPoolSize;
And I would never use a Class to hold this type of HardCoded Const variables.
而且我永远不会使用 Class 来保存这种类型的 HardCoded Const 变量。
回答by Some programmer dude
You generally shouldn't use e.g. const int
in a header file, if it's included in several source files. That is because then the variables will be defined once per source file (translation units technically speaking) because global const
variables are implicitly static, taking up more memory than required.
如果const int
头文件包含在多个源文件中,则通常不应在头文件中使用它。那是因为每个源文件(从技术上讲是翻译单位)将定义一次变量,因为全局const
变量是隐式静态的,占用的内存比所需的更多。
You should instead have a special source file, Constants.cpp
that actually defines the variables, and then have the variables declared as extern
in the header file.
你应该有一个特殊的源文件,Constants.cpp
它实际上定义了变量,然后extern
在头文件中声明变量。
Something like this header file:
像这样的头文件:
// Protect against multiple inclusions in the same source file
#ifndef CONSTANTS_H
#define CONSTANTS_H
extern const int CONSTANT_1;
#endif
And this in a source file:
这在源文件中:
const int CONSTANT_1 = 123;
回答by Andrew Rasmussen
Rather than making a bunch of global variables, you might consider creating a class that has a bunch of public static constants. It's still global, but this way it's wrapped in a class so you know where the constant is coming from and that it's supposed to be a constant.
与其创建一堆全局变量,不如考虑创建一个包含一堆公共静态常量的类。它仍然是全局的,但通过这种方式,它被包装在一个类中,因此您知道常量的来源以及它应该是一个常量。
Constants.h
常量.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
class GlobalConstants {
public:
static const int myConstant;
static const int myOtherConstant;
};
#endif
Constants.cpp
常量.cpp
#include "Constants.h"
const int GlobalConstants::myConstant = 1;
const int GlobalConstants::myOtherConstant = 3;
Then you can use this like so:
然后你可以像这样使用它:
#include "Constants.h"
void foo() {
int foo = GlobalConstants::myConstant;
}
回答by Louis Strous
It seems that bames53's answer can be extended to defining integer and non-integer constant values in namespace and class declarationseven if they get included in multiple source files. It is not necessary to put the declarations in a header file but the definitions in a source file. The following example works for Microsoft Visual Studio 2015, for z/OS V2.2 XL C/C++ on OS/390, and for g++ (GCC) 8.1.1 20180502 on GNU/Linux 4.16.14 (Fedora 28). Note that the constants are declared/defined in only a single header file that gets included in multiple source files.
似乎 bames53 的答案可以扩展到在命名空间和类声明中定义整数和非整数常量值,即使它们包含在多个源文件中。不必将声明放在头文件中,而是将定义放在源文件中。以下示例适用于 Microsoft Visual Studio 2015、OS/390 上的 z/OS V2.2 XL C/C++ 以及 GNU/Linux 4.16.14 (Fedora 28) 上的 g++ (GCC) 8.1.1 20180502。请注意,常量仅在包含在多个源文件中的单个头文件中声明/定义。
In foo.cc:
在 foo.cc 中:
#include <cstdio> // for puts
#include "messages.hh"
#include "bar.hh"
#include "zoo.hh"
int main(int argc, const char* argv[])
{
puts("Hello!");
bar();
zoo();
puts(Message::third);
return 0;
}
In messages.hh:
在messages.hh中:
#ifndef MESSAGES_HH
#define MESSAGES_HH
namespace Message {
char const * const first = "Yes, this is the first message!";
char const * const second = "This is the second message.";
char const * const third = "Message #3.";
};
#endif
In bar.cc:
在 bar.cc 中:
#include "messages.hh"
#include <cstdio>
void bar(void)
{
puts("Wow!");
printf("bar: %s\n", Message::first);
}
In zoo.cc:
在zoo.cc中:
#include <cstdio>
#include "messages.hh"
void zoo(void)
{
printf("zoo: %s\n", Message::second);
}
In bar.hh:
在 bar.hh 中:
#ifndef BAR_HH
#define BAR_HH
#include "messages.hh"
void bar(void);
#endif
In zoo.hh:
在动物园.hh:
#ifndef ZOO_HH
#define ZOO_HH
#include "messages.hh"
void zoo(void);
#endif
This yields the following output:
这会产生以下输出:
Hello!
Wow!
bar: Yes, this is the first message!
zoo: This is the second message.
Message #3.
The data type char const * const
means a constant pointer to an array of constant characters. The first const
is needed because (according to g++) "ISO C++ forbids converting a string constant to 'char*'". The second const
is needed to avoid link errors due to multiple definitions of the (then insufficiently constant) constants. Your compiler might not complain if you omit one or both of the const
s, but then the source code is less portable.
数据类型char const * const
表示指向常量字符数组的常量指针。第一个const
是需要的,因为(根据 g++)“ISO C++ 禁止将字符串常量转换为 'char*'”。第二个const
是为了避免由于(然后不够恒定)常量的多个定义而导致的链接错误。如果您省略一个或两个const
s,您的编译器可能不会抱怨,但是源代码的可移植性较差。