これはおそらく非常に簡単なことですが、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 };
しかし、これは機能しません。
構文が間違っているか何かがありますか?これへの正しい方法は何ですか?
どうもありがとう。
extern
をヘッダーファイルの宣言に追加します。
extern int lettersArr[26];
(また、配列を変更する予定がない限り、const
も追加することを検討してください。)
定義にはタイプが必要です。 int
(またはconst int
):
int lettersArr[26] = { letA, /*...*/ };
ヘッダ:
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));
ヘッダーの内容を次のように変更します。
extern int lettersArr[26];
そのため、定義ではなく宣言になります。
他の人は、配列の初期化を実装ファイルに移動する方法を説明しました。これは質問に正確に答えているわけではありませんが、知っておくと便利な回避策です。
C++ヘッダーファイルで配列を宣言したい
ヘッダーファイルに初期化を含めるなど、ヘッダーファイルに配列をすべて含めたい場合は、次のことができます。
それを与える内部リンケージstatic
を使用して、または
インライン関数でlocal staticを使用する(効果的に外部リンケージをサポートする)、または
少しテンプレートトリックを使用します(外部リンケージもサポートします)。
最後の2つの解決策は、C++に「inline
」データがないための回避策です。つまり、複数の変換単位で同じ名前空間スコープオブジェクトを定義する機能。関数に対してはinline
を介してそれがありますが、残念ながらオブジェクトに対してはそうではありません:何らかの回避策を講じなければ、リンカーは複数の定義について抗議するだけです。
これは一般的に良い解決策ではありません。ヘッダーが含まれる各翻訳単位に1つの配列を作成します。ただし、比較的小さい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;
}
これはおそらく、他のソリューションのいずれかを選択するための最優先の理由がない場合に使用する、一般に「最良の」ソリューションです。良いことの1つは、動的な初期化を簡単に提供できることです。ここでは、配列に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 [〜#〜]、One Definition Ruleは、テンプレートの特別な免除:
#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;
}
乾杯
次の方法でできます:
ヘッダーに
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 };
ヘッダーファイルの1つからの抜粋を以下に示します(実装.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>