web-dev-qa-db-ja.com

C ++ヘッダーで配列をどのように宣言しますか?

これは 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つのステップで宣言して初期化することは可能ですか?より良い代替案はありますか?

22
xan

キーワード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"};
18

これは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* []は、コンパイラが各インスタンスに割り当てる必要があるスペースの量を示していません(配列はインスタンス変数として宣言されています)。

さらに、その配列は本質的に定数値であるため、おそらくその配列を静的にする必要があります。

3
Carl Seleborg