• ベストアンサー

クラスがメンバーとしてクラスを持つ時の宣言について

自作クラスMainClassがMyClassというクラスをメンバー変数として持つ場合、宣言時に引数をいくつか持つコンストラクタを呼び出そうとすると構文エラーとなります。 class MyClass { public: MyClass(int, int); } class MainClass { private: MyClass myclass(10,10); } このような宣言はできないのでしょうか。 引数なしのコンストラクタは呼び出せているようです。

質問者が選んだベストアンサー

  • ベストアンサー
  • KoHal
  • ベストアンサー率60% (110/181)
回答No.2

クラス定義内でメンバの初期化は出来ません。 例外として static constの整数型メンバのみ初期化が認められていますが。 >引数なしのコンストラクタは呼び出せているようです。 勘違いです。 MyClassのコンストラクタが呼び出されるのはMainClassのコンストラクタ内です。 //MainClassのクラス定義 class MainClass { private:  MyClass myclass; //… }; //MainClassのコンストラクタ定義 MainClass::MainClass() : myclass(10,10) { //… } 初期設定リスト「:myclass(10,10)」を指定しなければMyClassのデフォルトコンストラクタが暗黙に呼び出されます。 なお、MyClassのコンストラクタで引数に初期値を指定しておく手もあります。 MyClass { public:  MyClass(int=10, int=10); //… }; この場合、MainClassのコンストラクタでmyclassの初期設定リストを省略しても所期の結果が得られます。 しかし、初期値を設定した場合でも初期設定を明示することをお勧めしますが。

lilillii
質問者

補足

回答ありがとうございます。 納得できました。ということは、引数が違う物をいくつか作成する場合は、宣言以外のところでnewするか、セッターなどで設定するしかないということですか? あとひとつ気になったのですが、 >static constの整数型メンバのみ初期化が認められています とありますが、現在ヘッダファイルに2次元配列の変数を宣言してincludeしています。 array.h int test[3][3]={{1,2,3},{1,2,3},{1,2,3}}; include "array.h" class MainClass { private:  MyClass myclass; //… }; これだとMainClassの関数で自由にtest変数を使えるのですがこれは良くない方法なのでしょうか。 自分では、test[][]はメンバー変数で初期化しているつもりでしたが良く考えるとおかしいですね。 この変数はどんな扱いになっているのでしょうか?

その他の回答 (2)

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.3

>引数が違う物をいくつか作成する場合 ご質問の趣旨が分かりにくいです。 MainClass::myclaasの初期化に使う引数ということでしょうか? それなら、1つの手としてはMainClassのコンストラクタにそのための引数を追加する方法がありますが。  MainClass::MainClass( int a, int b ) : myclass( a, b ) {} >array.hについて include指令は、そのファイルの内容を単純に挿入するだけです。 手作業でファイルの内容をコピー&ペーストするのとなんら変わりません。 No.2補足のコードなら、testはMainClassの外で、つまりグローバル変数として定義されてますね。 ヘッダファイル内でグローバル変数を定義するのは避けたほうがよろしいかと思います。 C++だとグローバル変数自体をあまり使いませんし。

lilillii
質問者

お礼

回答、ありがとうございました。 MainClassで使うmyclassの変数が複数あり、それぞれの引数が異なる場合ということです。 myclassがひとつならその方法でできそうです。 クラスにもグローバル変数というのがあったのですね。 知りませんでした。 配列は100×100くらいの大きさなので、プログラムに直に書くのも大変なので、とりあえずはグローバルで扱っていこうと思います。そのうち、リソースにするか別ファイルに記載して読み込むようにしようと思います。 どうもありがとうございました。

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.1

class MainClass { private: MyClass myclass(10,10); public: MainClass() : myclass(10,10) { } }; という感じでコンストラクタから宣言してはどうでしょうか?

lilillii
質問者

お礼

回答ありがとうございました。 他の方の回答で宣言時に初期化はできないことがわかりました。

関連するQ&A

  • C++でfriendクラスにしているのにprivateメンバにアクセスできない

    C++でメンバ変数をprivateにして、特定のクラスにだけ公開するようにクラスをfriend指定したのですがprivateメンバにアクセスできませんとエラーが吐かれてしまいます。 先行宣言したりもしてみたのですがどうしても使用できません。 何か心当たりのあるかた教えてください。 class A { friend class B; private: int a; }; class B { public: void test( A *a ) { a->a = 0; } }; コードは違いますがこんな感じのことをしたいのです。 /* コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。よろしくお願いします。 */

  • C++ クラス概念

    以下の違いがよく理解できていません。 どなたかご教授お願い致します。 (1)クラスのメンバー変数に static を付けた場合と、 メンバーではない変数に static を付けた場合の違い (2)クラスのメンバー関数に static を付けた場合と、 メンバーではない関数に static を付けた場合の違い [プログラム例] class MyClass { public: static int internalCount; static void func(MyClass& a) {/* ... */} }; static int i; static void f(MyClass& a) { /* ... */ }

  • マネージクラスについて

    マネージクラスで可変長の引数を使いたいのですが、 public ref class CTest { public: CTest(); // コンストラクタ ~CTest(); // デフォルトコンストラクタ !CTest(); // ファイナライザ Msg(PSTR str, ...); // 可変長引数 }; とすると、 「error C3269: マネージ クラスのメンバ関数は '...' と共に宣言することはできません」 というエラーがでてしまいます。 なんとかしてマネージクラスで 可変長の引数を使いたいのですが、方法がわかりません。分かる方いますでしょうか?

  • C++変数宣言時のコンストラクタについて

    Java開発をこれまでやってきたのですが、 C++を学ぼうとしています。 C++では下記のように宣言した場合hogeは インスタンスになり、Hogeクラスのコンストラクタが呼ばれるようなのですが、 Hoge hoge; Hogeクラスのコンストラクタが下記のような引数を持つものしか定義されていなかった場合は どの様な振る舞いをするのでしょうか? Hoge(int num); Javaでは引数の有るコンストラクタしか宣言しなかった場合はデフォルトコンストラクタは 作られなかったと思うのですが、c++では引数のないデフォルトコンストラクタができてるのでしょうか? また、デフォルトコンストラクタが出来ていなかった場合、 Hoge hoge; というようにプリミティブ型のような変数宣言の仕方で引数有りのコンストラクタを呼ぶことは出来るのでしょうか?

  • 基本クラスと派生クラスの宣言順序

    C++のクラスの宣言は、基本クラスから先に宣言しないといけないのでしょうか。 例. 次の順で宣言するとエラーになる。 class A : public B { public: private: } calss B { public: private: }

  • 配列であるメンバのコンストラクタを呼ぶ方法

    C++のクラスについて教えていただけないでしょうか。以下のような場合、 class ClassA {   int A; public:   ClassA(int a): A(a) {} }; class ClassB {   ClassA A; public:   ClassB(): A(10) {} }; class ClassC {   ClassA A[2]; public:   ClassC() {} //配列であるメンバのコンストラクタを呼び出したい }; ClassBがClassAのコンストラクタを呼ぶには上記のような方法で良いと思うのですが、ClassCのようにメンバが配列の場合、そのメンバのコンストラクタを呼ぶにはどのようにしたら良いのでしょうか。ご教授をお願いします。

  • 派生クラスのメンバを基底クラスの参照に代入(C++

    文末のコードのように、 基底クラスで、派生クラスのメンバの参照を持つのはまずいでしょうか。 (classではなくstructにしているのは質問上でのpublic:の省略のためだけです) 初期化順序的には、基底クラスの参照先は、 基底クラスのコンストラクタが走る時点で初期化されていないので、 コンストラクタ内で参照に対して何かしようとすると問題になると思っています。 基底クラスのコンストラクタ内で派生クラスメンバの参照に対して何かしなければ、 参照は有効で、派生クラスのコンストラクタ実行後であれば 問題なく動くと思ってよいでしょうか。 struct A { int& m_ref; A(int& ref) : m_ref(ref) { } }; struct B : public A { int m_obj; B() : A(m_obj) { } };

  • C++ クラスをメンバにもつクラスについて

    お世話になります。C++初心者でうまくコードが書けません(><) クラス1と2があり、クラス1のメンバにはクラス2があります。 メインでクラス1をインスタンス化してクラス2のfunc2を呼び出します。 func2ではクラス1のインスタンスから呼び出された場合にクラス1の m_int1を取得します。 Class Class1{ public:  int m_int1;  Class2 m_Class2; }; Class Class2{ public: void func2(); }; void Class2::func2(){  /*ここの記述方法が分かりません*/  /*C1から呼び出されたらC1のm_int1に100を入れる*/  /*以下間違え*/  class1 C2_1;/*別のclass1のオブジェクトなのでこれに入れてもダメっぽい*/  C2_1.m_int1 = 100; } void main(){  class1 C1;  C1.m_int1 = 10;  C1.m_class2.func(); } C1.m_class2.func()の中から呼び出したC1にアクセスする方法が 分かりません(TT)。実体がまだあるのだからアクセスする方法は あると思うのですが・・・ どなたかよろしくお願いします。

  • クラスの中にクラス

    お世話になります。 クラス1のメンバにクラス2を入れ、クラス1のコンストラクタでクラス2を操作しようとすると例外で落ちてしまいました。 しかしコンストラクタ内で別にクラス2をつくると落ちませんでした。 class Class1 {  Class2 cl2; ←クラス1のメンバにクラス2を入れる public:  Class1(); }; Class1::Class1() {  cl2.hoge(); ←落ちた  /*  ↓だと落ちなかった  Class2 _cl2;  _cl2.hoge();  */ } これは何故でしょうか? ちなみにクラスはstd::mapを使用し、hoge()はinsert_typeでした。

  • クラスメンバの中で配列を利用したい

    Cで書いたプログラムをC++に移植してます。 普通の変数はクラスメンバに置き換えてしまえばよろしいのですが、 配列の場合そのままクラスメンバに置き換えたら 問題が発生します。(予想はついていたのですが…) class test{ private: int m_test[100]; }; クラスメンバを配列に設定するにはどうすればよいですか?

専門家に質問してみよう