- ベストアンサー
C++でクラスのインスタンス化が参照
他の人のC++ プログラムを見ているのですが、 クラスをインスタンス化する部分で CLASS_CAR car; CLASS_TRAIN &train; のように書かれているのですが 後者の意味が分からないのですが、これは何をしているのでしょう? 引数なら 元の変数のエイリアスを宣言するところなのでしょうが、 これだと 何に対するエイリアスだか分からず 困っています。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
クラスの宣言部でのこの表記であれば、参照型に絞られるはずです。 参照型は、単純に、機能制限付き(初期化後以降置き換え出来ない、アドレス移動できない)で表記の異なるポインタ、と思って差し支えないです。 参照型は、使うときは↓と同じで、引数として取った場合と何ら変わりありません。 struct PT3 { float x, y, z; }; PT3 pt3; PT3* p = &pt3; //ポインタの場合 p->x = 0.0f; PT3& r = pt3; //参照の場合 r.y = 1.0f; 参照型の場合は後で代入できず(型名* const 変数名; の場合と同じ)それゆえ CLASS_TRAIN &train; をメンバ変数として宣言するならば コンストラクタの「初期化子リスト」を使って初期化する必要があります。 例) class A { const double b; double a; CLASS_TRAIN &train; int& num; public: A( double b_, CLASS_TRAIN& t, int& i ) : b(b), train(t), num(i) { a = 0; //これは初期化リストじゃなくてもOK } Void ChangeNum( int i ){ num = i; } CLASS_TRAIN& GetTrain() const { return train; } }; 上記コンストラクタの : から始まり、{ までが初期化子リストです。 参照型だけでなく const なメンバ変数も初期化子リストで初期化しなければいけません。 (というよりconstを中心に考えて、参照が内部的に 型名* const の、置き換え不能なポインタのように扱われる、と考えた方が分かりやすいかもしれません。) それ以外の変数は double a; については { のあとで初めて a = 0; としているように、初期化子リストで初期化する必要がありません。 constといっても const 型名* 変数名; の場合は、ポインタそのものの指す先は変更可能なので、初期化子リストで初期化する必要はありません。あくまで、「その型の変数そのものがconst」な場合が 初期化子リストでの初期化が必須なケースです。 もちろん、初期化子リストで初期化する必要がない変数を初期化子リストで初期化しても、何ら問題ありません。 というより、単純な初期化を必ずするべき変数なら、初期化子リストで初期化した方が コンパイル後の機械語としてのコードは短くなる、可能性はあります。(最適化によって同じになる可能性はありますが) 逆に長くなる、という事は(コンパイラに問題がない限り)ないはずです。 使用法としては、上記クラスAなら例えばこんな感じになります。 CLASS_TRAIN tr; int hontai; A a( 0, tr, hontai ); //3つの引数を持つコンストラクタ a.ChangeNum( 3 ); //aの内部のnumを介してhontaiが書き変わる CLASS_TRAIN& ref_tr = a.GetTrain(); ref_tr.CLASS_TRAINのメンバ関数(); などなど。
その他の回答 (1)
- Tacosan
- ベストアンサー率23% (3656/15482)
こんな一部分だけ見せられても分かりません. そもそも「クラスをインスタンス化する部分」とは何のことでしょうか?
補足
すみません。 自分でもこれでは 質問としてなりたっていないと思い、 質問を削除しようとしていましたが間に合いませんでした。 該当箇所は、あるクラスの中の Public のメンバクラスを 宣言している部分でした。 コードを全部載せるられず、うまく質問もできなくて申し訳ないのですが、 以下のようのことが もやもやしています。 回答不能でしたら **を見て勉強しろといっていただけると助かります。 C++は、初心者なので見当はずれのことを言っているかもしれません * メンバクラスの宣言部に このように書かれているのが、参照を宣言しているのか それとも全然別のことをしているのかがまずわかりません。 * 参照だとして 参照相手となるものが無い 参照だけの宣言とは何なのか あとから参照相手をきめることができるのか? * それともコンストラクタで生成される名無しのクラスへの 参照となるのか?
お礼
ありがとうございます。 初めての質問ですがこんなに丁寧に解説していただいてたいへん感謝しています。 まだ、完全理解には至ってませんが、トンネルの出口が見えてきました、後は自力で進めそうです。 やっぱりコンストラクタの初期化子リストをきちんと理解していなかったのが問題でした。