これは this などの他のいくつかの質問と、他のいくつかの質問に関連しています。
この質問 などでは、文字列配列を1つのナイスステップで宣言して初期化できることがわかります。次に例を示します。
const char* const list[] = {"Zip", "zam", "bam"}; //from other question
これは、問題のない関数の実装、またはスコープ外の.cppファイルの本文で行うことができます。
私がやりたいのは、私が使用しているクラスのメンバーとして、次のような配列を持つことです:
class DataProvider : public SomethingElse
{
const char* const mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"};
public:
DataProvider();
~DataProvider();
char* GetData()
{
int index = GetCurrentIndex(); //work out the index based on some other data
return mStringData[index]; //error checking and what have you omitted
}
};
しかし、コンパイラは文句を言い、私はその理由を理解できないようです。このような配列をクラス定義の1つのステップで宣言して初期化することは可能ですか?より良い代替案はありますか?
キーワードstaticおよび外部初期化を使用して、配列をクラスの静的メンバーにします。
ヘッダーファイル:
class DataProvider : public SomethingElse
{
static const char* const mStringData[];
public:
DataProvider();
~DataProvider();
const char* const GetData()
{
int index = GetCurrentIndex(); //work out the index based on some other data
return mStringData[index]; //error checking and what have you omitted
}
};
.cppファイル:
const char* const DataProvider::mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"};
これはC++では不可能です。配列を直接初期化することはできません。代わりに、必要なサイズ(この場合は4)を指定し、DataProviderのコンストラクターで配列を初期化する必要があります。
class DataProvider {
enum { SIZEOF_VALUES = 4 };
const char * values[SIZEOF_VALUES];
public:
DataProvider() {
const char * const v[SIZEOF_VALUES] = {
"one", "two", "three", "four"
};
std::copy(v, v + SIZEOF_VALUES, values);
}
};
配列を直接初期化することはできないため、配列内のポインターの一貫性をあきらめる必要があることに注意してください。ただし、後でポインタを正しい値に設定する必要があるため、ポインタは変更可能である必要があります。
それでも配列の値がconstである場合、静的配列を使用するのが唯一の方法です。
/* in the header file */
class DataProvider {
enum { SIZEOF_VALUES = 4 };
static const char * const values[SIZEOF_VALUES];
};
/* in cpp file: */
const char * const DataProvider::values[SIZEOF_VALUES] =
{ "one", "two", "three", "four" };
静的配列を持つことは、すべてのオブジェクトがその配列を共有することを意味します。したがって、メモリも節約できます。
このように配列を宣言できない理由は(const char * [])です。
const char* []
は、コンパイラが各インスタンスに割り当てる必要があるスペースの量を示していません(配列はインスタンス変数として宣言されています)。さらに、その配列は本質的に定数値であるため、おそらくその配列を静的にする必要があります。