構造体テーブルをメンバ変数にするには?


たか  2003-09-22 23:45:45  No: 52173  IP: [192.*.*.*]

下記のような構造体テーブルをクラスのconstメンバ変数にしたいのですが、
方法が分かりません。ご存知の方がおられましたら教えてください。


例)
static testtable
{
  char a[2];
  char b[2];

};

構造体テーブル
testtable [] = 
{
 {"a", "1"}, {"b", "2"}, {"c", "3"}
};

このtesttableをクラスのconstメンバ変数にしたいのですが、
どのように定義し、どのタイミングで初期化するのかが分かりません。

編集 削除
ぴのきよ  2003-09-23 00:45:46  No: 52174  IP: [192.*.*.*]

構造体の宣言と初期化ですよね?
これでわかりますか?
*****************************************************************
// 例1------------------------------------------------->
struct tag_test
{
  char a[2];
  char b[2];
};
const struct tag_test test1[] = {{"a", "b"},{"c", "d"}};
//<例1-------------------------------------------------
// 例2------------------------------------------------->
typedef struct tag_test2
{
  char a[2];
  char b[2];
}_TEST2;
const _TEST2 test2[] = {{"a", "b"},{"c", "d"}};
//<例2-------------------------------------------------

int main(int argc, char* argv[])
{
  //例3------------------------------------------------->
  const struct tag_test test3[] = {{"e", "f"},{"g", "h"}};
  //<例3-------------------------------------------------
  //例4------------------------------------------------->
  const _TEST2 test4[] = {{"e", "f"},{"g", "h"}};
  //<例4-------------------------------------------------

  return 0;
}
******************************************************************

編集 削除
ぴのきよ  2003-09-23 01:52:25  No: 52175  IP: [192.*.*.*]

ごめんなさい。
>このtesttableをクラスのconstメンバ変数にしたいのですが、
ということでしたね。

定数はメンバ変数にはできません。
外部から書き換えられたくないという意図なら
privateのメンバ変数としたらどうでしょうか?

編集 削除
たか  2003-09-23 08:45:19  No: 52176  IP: [192.*.*.*]

どうも。たかです。回答いただきありがとうございます。

>定数はメンバ変数にはできません。

staticメンバ変数とか、constメンバ変数とかがあると
思うのですが、そういったものにすることはできない
のでしょうか?。

編集 削除
YuO  2003-09-23 10:45:52  No: 52177  IP: [192.*.*.*]

> 下記のような構造体テーブルをクラスのconstメンバ変数にしたいのですが、
> 方法が分かりません。ご存知の方がおられましたら教えてください。

配列自体をconst memberにすることはできません。
初期化できないからです。

ただし,配列をクラス化すると,できないこともないようになります。
template <typename T, unsigned N> class Array {
private:
    T data_[N];

public:
    Array (void) {} // 一切の初期化をしない
    template <class InIt> Array (InIt first, InIt last) // [first, last)を使って初期化する
    {
        std::copy(first, last, data_);
    }

    T & operator[] (unsigned index)
    {
        return data_[index];
    }
    const T & operator[] (unsigned index) const
    {
        return data_[index];
    }
};
なんてクラスを用意して,
const testtable temp_[] = {
    { "a", "1" }, { "b", "2" }, { "c", "3" }
};
なんていう初期化用のデータも用意してしまえば,あとは,
class foo {
    const Array<testtable, sizeof(temp_) / sizeof(temp_[0])> array_;

public:
    foo (void);
};
foo::foo (void) : array_(temp_, temp_ + sizeof(temp_) / sizeof(temp_[0])) { }
のようにして配列が作れます。


> 定数はメンバ変数にはできません。

定数メンバは作成できます。
mem-initializer使えば初期化できます。

編集 削除
ぴのきよ  2003-09-23 15:10:24  No: 52178  IP: [192.*.*.*]

すみません。勉強不足でしたm(_ _)m
ところでmem-initializerとは具体的に何ですか?

編集 削除
YuO  2003-09-23 16:09:34  No: 52179  IP: [192.*.*.*]

> ところでmem-initializerとは具体的に何ですか?

member initializerの文法表記上での記述です。
>foo::foo (void) : array_(temp_, temp_ + sizeof(temp_) / sizeof(temp_[0])) { }

>array_(temp_, temp_ + sizeof(temp_) / sizeof(temp_[0]))
の部分です。


基底クラス及びメンバの初期化を行うために,専用の構文が用意されています。
簡単に書くと,コンストラクタは,
クラス名(仮引数群) : 基底クラス名(引数群), メンバ変数名(引数群), /* 他の基底クラスとかメンバ変数とか */
{
    /* コンストラクタ本体 */
}
のようになります。

メンバ変数が組み込み型の変数の場合,引数群には
・何も与えない
・その型に変換可能な型の値
のどちらかが指定できます。
何も与えなかった場合,0が指定されたのと同じ扱いです。
#初期化しなかった場合は不定値です。

メンバ変数がクラス型の場合や,基底クラスに関して,
引数群にはコンストラクタの引数として働く値を渡します。
何も与えなかった場合,仮引数を受け取らないコンストラクタを呼び出します。
該当するコンストラクタがなければ当然コンパイル時にエラーになります。
#初期化しなかった場合,引数無しで初期化されます。


ちなみに,mem_initializerの記述順序は初期化順序を左右しません。
初期化順序は,基底クラスが先で,先に定義されているメンバから順に初期化されます。
class foo {
    int n1_;
    int n2_;
public:
    foo (int n1, int n2) : n2_(n2), n1_(n2_ - n1) {}
};
があったとき,n1_の値は不定です。
#n1_が先に初期化され,n2_が後から初期化されるため。

編集 削除
ぴのきよ  2003-09-23 16:49:58  No: 52180  IP: [192.*.*.*]

YuOさんありがとうございます。
勉強になりました。

たかさん割り込んじゃってすみませんでした。m(_ _)m

編集 削除
たか  2003-09-23 22:25:19  No: 52181  IP: [192.*.*.*]

YuOさん、ぴのきよさん、いろいろ教えていただきありがとうございました。
大変参考になりました。特に、配列をクラス化する方法はすぐに使用してみます。

mem_initializerについては最近まで知らず、仕事で人から教えられて初めて
知ったのですが、mem_initializerはC++の入門書レベルではなかなか載って
ないと思うのですが、こういったことについても書かれている参考書とか
ご存知でしたら教えていただけませんか?

編集 削除
しるきぃ  2003-09-24 17:17:26  No: 52182  IP: [192.*.*.*]

マルチポストか、、、
マナー悪いね。

編集 削除
Eighty  2003-09-24 17:23:56  No: 52183  IP: [192.*.*.*]

http://mfc.acty-net.ne.jp/ml/mfc/msgView.cgi?Lno=46152

編集 削除