下記のような構造体テーブルをクラスのconstメンバ変数にしたいのですが、
方法が分かりません。ご存知の方がおられましたら教えてください。
例)
static testtable
{
char a[2];
char b[2];
};
構造体テーブル
testtable [] =
{
{"a", "1"}, {"b", "2"}, {"c", "3"}
};
このtesttableをクラスのconstメンバ変数にしたいのですが、
どのように定義し、どのタイミングで初期化するのかが分かりません。
構造体の宣言と初期化ですよね?
これでわかりますか?
*****************************************************************
// 例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;
}
******************************************************************
ごめんなさい。
>このtesttableをクラスのconstメンバ変数にしたいのですが、
ということでしたね。
定数はメンバ変数にはできません。
外部から書き換えられたくないという意図なら
privateのメンバ変数としたらどうでしょうか?
どうも。たかです。回答いただきありがとうございます。
>定数はメンバ変数にはできません。
staticメンバ変数とか、constメンバ変数とかがあると
思うのですが、そういったものにすることはできない
のでしょうか?。
> 下記のような構造体テーブルをクラスの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使えば初期化できます。
すみません。勉強不足でしたm(_ _)m
ところでmem-initializerとは具体的に何ですか?
> ところで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_が後から初期化されるため。
YuOさんありがとうございます。
勉強になりました。
たかさん割り込んじゃってすみませんでした。m(_ _)m
YuOさん、ぴのきよさん、いろいろ教えていただきありがとうございました。
大変参考になりました。特に、配列をクラス化する方法はすぐに使用してみます。
mem_initializerについては最近まで知らず、仕事で人から教えられて初めて
知ったのですが、mem_initializerはC++の入門書レベルではなかなか載って
ないと思うのですが、こういったことについても書かれている参考書とか
ご存知でしたら教えていただけませんか?
マルチポストか、、、
マナー悪いね。
http://mfc.acty-net.ne.jp/ml/mfc/msgView.cgi?Lno=46152
編集 削除