ページ 11

関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月20日(土) 21:57
by sign
main内で
Func(1);
と実行したとします。Func関数は下に書きます。
Func関数の中で、引数に応じて異なるクラスを同じ変数名で作成したいのですが、
単純なif文やswitch case文ではローカル変数になってしまい、その外では使えません。
#if文で書こうとしたのですが、引数アリでも無しでも何故かClassAの文、つまり
#if (num == 0)
にしかいけません。

コード:

void Func(int num = 2) {

	#if (num == 0)
	ClassA maker();
	#elif (num == 1)
	ClassB maker();
	#elif (num == 2)
	ClassC maker();
	#else
	ClassD maker()
	#endif

	maker.create();
}	
これの理由と、解決策が知りたいです。
よろしくお願いします。

Re: 関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月20日(土) 22:05
by みけCAT
#ifとか#elifとか#elseとか#endifはプリプロセッサ命令のため、実行時のnumの値には関係ありません。
解決策は…ごめんなさい、すぐには思いつきません。

Re: 関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月20日(土) 22:23
by derok
クラスということはC++ですか?
もしそうなら、ClassA~DクラスがBase Classを継承して、
BaseClassのポインタに代入すればいいのではないのでしょうか?

Re: 関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月20日(土) 22:35
by zxc
  異なるクラスを同じ名前で使いたいのならば、共通の基底クラスをそれぞれが継承して、基底クラス型で実体を作ってやればいいのではないでしょうか。もしくはif文やswitch文のreturnで「newしたポインタ等」を返すことになると思います。いずれにしてもそれぞれ子クラスの実体が同時に複数存在しないことになりそうですが。
  型に応じた振る舞いはそれぞれの子クラスに記述したり、type_infoで判断してやれば、なんとかなるかもしれません。

Re: 関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月20日(土) 23:10
by せんちゃ
プリプロセッサの使い方がそもそも間違っています。
プリプロセッサはコンパイル前に処理されます、当然コードに記述している変数は対象になりません。
numの値によって生成するクラスを変えたい場合は

コード:

void Func( int num = 2 ) {
	Class* maker = NULL;
	switch( num ){
		case 0 : maker = new ClassA(); break;
		case 1 : maker = new ClassB(); break;
		case 2 : maker = new ClassC(); break;
		default : maker = new ClassD(); break;
	}
	maker->create();
}
みたいなのが現実的なのではないでしょうか。

Re: 関数の中で#if #elif #endif を使いたいのですが、理解できません

Posted: 2013年4月21日(日) 21:49
by sign
ありがとうございます!
newを使うのですね。考え方が分かって良かったです。
#ifは動的に動かないことを知りました。
重ねて、ありがとうございます。