ページ 11

内部クラスのコンストラクタ定義

Posted: 2015年3月17日(火) 19:18
by SoiSoiMilk
お世話になっています。C++なのですが、内部クラスのコンストラクタについてです。
このコードのように、hogeクラス内にhogeHogeクラスを生成し、引数がhogeHogeクラスのメンバ
であるコンストラクタを宣言しました。

気持ち悪いコードではあると思うのですが、
このコード、どこがどうしておかしいのか、スマートに書くとしたらどうしたらいいのか、
また、そもそもhogeHogeクラスのメンバ変数をhogeHogeクラスのコンストラクタの引数にして、
hogeクラスのメンバ変数に代入なんてできないよ、などご指摘いただければ幸いです。
よろしくお願いします。

コード:

class hoge{
public :
	int hogeInt;
	class hogeHoge{
		public :
			int hogeHogeInt;
			hogeHoge(int hogeHogeInt);
	};
	hogeHoge::hogeHoge(int hogeHogeInt)
	{
		hogeInt = hogeHgeInt;
	}	
};

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月17日(火) 19:50
by usao
オフトピック
まず「何をしたいのか」を明確にされたほうがよいのではないでしょうか.

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月17日(火) 20:14
by みけCAT
SoiSoiMilk さんが書きました:このコードのように、hogeクラス内にhogeHogeクラスを生成し、引数がhogeHogeクラスのメンバ
であるコンストラクタを宣言しました。
hogeHogeクラスのコンストラクタの引数は、たまたま名前がhogeHogeクラスのメンバと被っているだけで、hogeHogeクラスのメンバではありません。
SoiSoiMilk さんが書きました:また、そもそもhogeHogeクラスのメンバ変数をhogeHogeクラスのコンストラクタの引数にして、
hogeクラスのメンバ変数に代入なんてできないよ、などご指摘いただければ幸いです。
hogeHogeクラスのメンバ変数をhogeHogeクラスのコンストラクタの引数にすることなんてできないよ。
よって、そもそもhogeHogeクラスのメンバ変数をhogeHogeクラスのコンストラクタの引数にして、
hogeクラスのメンバ変数に代入なんてできないよ。

【訂正】以下のように、hogeHogeクラスのメンバ変数をhogeHogeクラスのコンストラクタの引数にすることはできます。

コード:

#include <cstdio>

class hogeHoge {
	public:
		int hogeHogeInt;
		hogeHoge(int a) {
			printf("%d\n", a);
		}
		void hogeHogeFunc() {
			hogeHoge h = hogeHogeInt;
			(void)h; // avoid warning
		}
};

int main(void) {
	hogeHoge h = 346;
	h.hogeHogeInt = 765;
	h.hogeHogeFunc();
	return 0;
}
SoiSoiMilk さんが書きました:

コード:

class hoge{
public :
	int hogeInt;
	class hogeHoge{
		public :
			int hogeHogeInt;
			hogeHoge(int hogeHogeInt);
	};
	hogeHoge::hogeHoge(int hogeHogeInt)
	{
		hogeInt = hogeHgeInt;
	}	
};
少し書き換えてみました。

コード:

class hoge{
public :
    int hogeInt;
    class hogeHoge{
        public :
            int hogeHogeInt;
            hogeHoge(int hogeHogeInt);
    };
};

hoge::hogeHoge::hogeHoge(int hogeHogeInt)
{
    hogeInt = hogeHogeInt;
}

int main(){}
エラーメッセージ(gcc4.8.2)

コード:

prog.cc: In constructor 'hoge::hogeHoge::hogeHoge(int)':
prog.cc:3:9: error: invalid use of non-static data member 'hoge::hogeInt'
    int hogeInt;
        ^
prog.cc:12:9: error: from this location
        hogeInt = hogeHogeInt;
        ^
このようなことをするのはinvalidなようですが、なぜでしょうか…?

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月17日(火) 23:40
by かずま
みけCAT さんが書きました:このようなことをするのはinvalidなようですが、なぜでしょうか…?
hogeInt は hogeクラスのメンバ関数です。
hogeInt は static ではありません。
したがって、hogeInt にアクセスするには hogeクラスのインスタンスが必要です。

コンストラクタ hogeHoge が呼び出される時、hogeHogeクラスの
インスタンスは存在して、this がそれを指していますが、
hogeクラスのインスタンスはどこにもありません。
だから、エラーです。

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月17日(火) 23:42
by かずま
かずま さんが書きました:hogeInt は hogeクラスのメンバ関数です。
訂正。メンバ関数ではなく、メンバ変数です。

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月18日(水) 00:09
by ISLe()
Javaで内部クラスというとインスタンスレベルで結び付く入れ子クラスのことを指しますが
C++の場合、単に名前空間に含まれるだけ、です。
Javaでいうところの静的入れ子クラス(static nested class)です。

Javaなら思った通りになりますよ。

Re: 内部クラスのコンストラクタ定義

Posted: 2015年3月18日(水) 09:39
by SoiSoiMilk
皆さん回答ありがとうございます。

やりたいことは、みけCATさんが書いてくださったコード

コード:

class hoge{
public :
    int hogeInt;
    class hogeHoge{
        public :
            int hogeHogeInt;
            hogeHoge(int hogeHogeInt);
    };
};
 
hoge::hogeHoge::hogeHoge(int hogeHogeInt)
{
    hogeInt = hogeHogeInt;
}
 
int main(){}
まさにこの通りですが、かずまさんのご指摘のとおりhogeのインスタンス化がどこにもされていないので
結局エラーになってしまうのですね。
ISLe() さんが書きました:Javaで内部クラスというとインスタンスレベルで結び付く入れ子クラスのことを指しますが
C++の場合、単に名前空間に含まれるだけ、です。
Javaでいうところの静的入れ子クラス(static nested class)です。

Javaなら思った通りになりますよ。
つまりC++ではこのようなことはできないうことですね(>_<)
なんだかもどかしいと思ってしまいますが、納得しました!
ありがとうございます。