在 C++ 头文件中声明数组并在 cpp 文件中定义它?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4391467/
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
Declare array in C++ header and define it in cpp file?
提问by tree-hacker
This is probably a really simple thing but I'm new to C++ so need help.
这可能是一件非常简单的事情,但我是 C++ 的新手,所以需要帮助。
I just want to declare an array in my C++ header file like:
我只想在我的 C++ 头文件中声明一个数组,如:
int lettersArr[26];
and then define it in a function in the cpp file like:
然后在 cpp 文件中的函数中定义它,例如:
lettersArr[26] = { letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ };
but this doesn't work.
但这不起作用。
Have I got the syntax wrong or something? What is the correct way to to this?
我的语法错误还是什么?对此的正确方法是什么?
Thanks a lot.
非常感谢。
采纳答案by aschepler
Add extern
to the declaration in the header file.
添加extern
到头文件中的声明。
extern int lettersArr[26];
(Also, unless you plan to change the array, consider also adding const
.)
(此外,除非您打算更改数组,否则还要考虑添加const
。)
The definition must have a type. Add int
(or const int
):
定义必须有一个类型。添加int
(或const int
):
int lettersArr[26] = { letA, /*...*/ };
回答by aschepler
Header:
标题:
extern int lettersArr[];
Source at the global scope:
全球范围内的来源:
int lettersArr[26] = { letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ };
or if you really want to do it in a function:
或者如果您真的想在函数中执行此操作:
Source at global scope:
全球范围内的来源:
int lettersArr[26];
Source in function:
函数中的来源:
int localLettersArr[26] = { letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ };
memcpy (lettersArr, localLettersArr, sizeof (localLettersArr));
回答by Kos
Change what you have in the header to:
将标题中的内容更改为:
extern int lettersArr[26];
so that it will become a declaration, not a definition.
这样它将成为一个声明,而不是一个定义。
回答by Cheers and hth. - Alf
Other have described how the array initialization can be moved to an implementation file, which is not exactly answering your question, but is a workaround that's useful to know.
其他人描述了如何将数组初始化移动到实现文件中,这并不能完全回答您的问题,但它是一种有用的解决方法。
I just want to declare an array in my C++ header file
我只想在我的 C++ 头文件中声明一个数组
If you really want to have the array all in your header file, including having the initialization in your header file, then you can
如果您真的想在头文件中包含所有数组,包括在头文件中进行初始化,那么您可以
give it internal linkageby using
static
, oruse a local staticin an inline function (which supports effectively external linkage), or
use a little template trick(also supports external linkage).
通过使用给它内部链接
static
,或在内联函数中使用本地静态(它支持有效的外部链接),或
使用一点模板技巧(也支持外部链接)。
The last two solutions are workarounds for the lack of "inline
" data in C++. That is, the ability to define the same namespace scope object in more than one translation unit. You have that for functions, via inline
, but unfortunately not for objects: without employing some workaround the linker will just protest about multiple definitions.
最后两个解决方案是针对inline
C++ 中缺少“ ”数据的解决方法。也就是说,能够在多个翻译单元中定义相同的命名空间范围对象。对于函数,通过inline
,但不幸的是,对于对象没有:如果不采用一些解决方法,链接器只会对多个定义提出抗议。
Internal linkage
内部联动
This is generally not a good solution. It creates one array in each translation unit where the header is included. But it's preferable for relatively small const
objects because it's so simple:
这通常不是一个好的解决方案。它在包含标题的每个翻译单元中创建一个数组。但它更适合相对较小的const
对象,因为它非常简单:
#include <stddef.h>
#include <iostream>
int const letA = 'A';
int const letB = 'B';
int const letC = 'C';
int const letD = 'D';
int const letE = 'E';
int const letF = 'F';
int const letG = 'G';
int const letH = 'H';
int const letI = 'I';
int const letJ = 'J';
int const letK = 'K';
int const letL = 'L';
int const letM = 'M';
int const letN = 'N';
int const letO = 'O';
int const letP = 'P';
int const letQ = 'Q';
int const letR = 'R';
int const letS = 'S';
int const letT = 'T';
int const letU = 'U';
int const letV = 'V';
int const letW = 'W';
int const letX = 'X';
int const letY = 'Y';
int const letZ = 'Z';
static int lettersArr[26] =
{
letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ
};
int main()
{
using namespace std;
for( int i = 0; i < 26; ++i )
{
cout << char( lettersArr[i] );
}
cout << endl;
}
Local static in inline function
内联函数中的局部静态
This is probably the generally "best" solution, to use when there is no overriding reason for choosing one of the other solutions. One nice thing is that it's easy to provide dynamic initialization. Here I've just assumed that you will never store 0 in the array (add some extra checking logic if that assumption doesn't hold):
这可能是通常的“最佳”解决方案,在没有选择其他解决方案之一的压倒一切的理由时使用。一件好事是很容易提供动态初始化。在这里,我只是假设您永远不会在数组中存储 0(如果该假设不成立,则添加一些额外的检查逻辑):
#include <stddef.h>
#include <iostream>
template< class Type, int n >
int countOf( Type (&)[n] ) { return n; }
typedef int LettersArray[26];
inline LettersArray& lettersArrayRef()
{
static LettersArray theArray;
if( theArray[0] == 0 )
{
// Assuming normal ASCII-based character set with contiguous alpha.
for( int i = 0; i < countOf( theArray ); ++i )
{
theArray[i] = i + 'A';
}
}
return theArray;
}
static LettersArray& lettersArr = lettersArrayRef();
int main()
{
using namespace std;
for( int i = 0; i < 26; ++i )
{
cout << char( lettersArr[i] );
}
cout << endl;
}
Template trick
模板技巧
The template trick works because the standard's ODR, One Definition Rule, makes a special exemption for templates:
模板技巧之所以有效,是因为标准的ODR,一个定义规则,对模板进行了特殊豁免:
#include <stddef.h>
#include <iostream>
int const letA = 'A';
int const letB = 'B';
int const letC = 'C';
int const letD = 'D';
int const letE = 'E';
int const letF = 'F';
int const letG = 'G';
int const letH = 'H';
int const letI = 'I';
int const letJ = 'J';
int const letK = 'K';
int const letL = 'L';
int const letM = 'M';
int const letN = 'N';
int const letO = 'O';
int const letP = 'P';
int const letQ = 'Q';
int const letR = 'R';
int const letS = 'S';
int const letT = 'T';
int const letU = 'U';
int const letV = 'V';
int const letW = 'W';
int const letX = 'X';
int const letY = 'Y';
int const letZ = 'Z';
template< class Dummy >
struct Letters_
{
static int array[26];
};
template< class Dummy >
int Letters_< Dummy >::array[26] =
{
letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ
};
static int (&lettersArr)[26] = Letters_<void>::array;
int main()
{
using namespace std;
for( int i = 0; i < 26; ++i )
{
cout << char( lettersArr[i] );
}
cout << endl;
}
Cheers & hth.,
干杯 & hth.,
回答by G O'Rilla
Here's a snippet from one of my header files (the implementation .cpp file accesses the array): (Use dummy::messages outside of the dummy namespace to access the array.)
这是我的一个头文件中的一个片段(实现 .cpp 文件访问数组):(在虚拟命名空间之外使用 dummy::messages 来访问数组。)
<pre>
namespace dummy {
const static string messages[] = {
"Unix does not echo the password field. Why do you think this is?",
"The firewall blocks external access to ouranos. You need to login to helios and ssh or sftp to ouranos",
"You need to experience of the command line. Not all systems have a gui.",
};
class Message {
public:
Message();
virtual ~Message();
string getMessage();
string getMessage( int index );
int getRandomNumber();
};
} /* namespace dummy */
</pre>
回答by Vlad
You can do it this way:
你可以这样做:
in header
在标题中
extern int lettersArr[26];
in .cpp
在.cpp
int lettersArr[26] = { letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ };
回答by Jana Baran
try:
尝试:
lettersArr = { 1, 2, 3, 4 }