在 C++ 中声明数组标头并在cpp文件中定义它?

发布于 2024-10-06 16:21:22 字数 429 浏览 8 评论 0原文

这可能是一件非常简单的事情,但我是 C++ 新手,所以需要帮助。

我只想在我的 C++ 头文件中声明一个数组,例如:

int lettersArr[26];

然后在 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 };

但这不起作用。

我语法错误还是什么?正确的方法是什么?

多谢。

This is probably a really simple thing but I'm new to C++ so need help.

I just want to declare an array in my C++ header file like:

int lettersArr[26];

and then define it in a function in the cpp file like:

    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

策马西风 2024-10-13 16:21:22

extern 添加到头文件的声明中。

extern int lettersArr[26];

(此外,除非您打算更改数组,否则请考虑添加 const。)

定义必须具有类型。添加 int (或 const int):

int lettersArr[26] = { letA, /*...*/ };

Add extern to the declaration in the header file.

extern int lettersArr[26];

(Also, unless you plan to change the array, consider also adding const.)

The definition must have a type. Add int (or const int):

int lettersArr[26] = { letA, /*...*/ };
春夜浅 2024-10-13 16:21:22

标题:

extern int lettersArr[];

全局范围内的源:

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 lettersArr[26];

函数中的源:

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));

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));
一杆小烟枪 2024-10-13 16:21:22

将标题中的内容更改为:

extern int lettersArr[26];

,以便它将成为声明,而不是定义。

Change what you have in the header to:

extern int lettersArr[26];

so that it will become a declaration, not a definition.

面犯桃花 2024-10-13 16:21:22

其他人描述了如何将数组初始化移动到实现文件,这并不能完全回答您的问题,但这是一种值得了解的解决方法。

<块引用>

我只想在我的 C++ 头文件中声明一个数组

如果您确实希望将数组全部放在头文件中,包括在头文件中进行初始化,那么您可以

  • 给它内部链接 使用static,或

    使用

  • 使用本地内联函数中的 static(支持有效的外部链接),或者

  • 使用一点模板技巧(也支持外部链接)。

最后两个解决方案是针对 C++ 中缺少“inline”数据的解决方法。也就是说,能够在多个翻译单元中定义相同的命名空间范围对象。您可以通过 inline 为函数提供此功能,但不幸的是,不适用于对象:如果不采用某些解决方法,链接器只会抗议多个定义。

内部链接

这通常不是一个好的解决方案。它在包含标头的每个翻译单元中创建一个数组。但对于相对较小的 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;
}

内联函数中的局部静态

这可能是通常“最佳”的解决方案,当没有选择其他解决方案之一的首要原因时使用。一件好事是很容易提供动态初始化。在这里,我只是假设您永远不会在数组中存储 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;
}

模板技巧

模板技巧之所以有效,是因为标准的 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 &呵呵,

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

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 linkage by using static, or

  • use a local static in an inline function (which supports effectively external linkage), or

  • use a little template trick (also supports external linkage).

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.

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:

#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):

#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:

#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.,

心的位置 2024-10-13 16:21:22

这是我的头文件之一的片段(实现 .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>

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.)

<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>
笑看君怀她人 2024-10-13 16:21:22

你可以这样做:

标头中

extern int lettersArr[26];

在.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 };

You can do it this way:

in header

extern int lettersArr[26];

in .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 };
孤千羽 2024-10-13 16:21:22

尝试:

lettersArr = { 1, 2, 3, 4 }

try:

lettersArr = { 1, 2, 3, 4 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文