ifやswitchを使わない条件分岐について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
なんちゃってプログラマ

ifやswitchを使わない条件分岐について

#1

投稿記事 by なんちゃってプログラマ » 15年前

始めまして。

例えばオミクジのプログラムを作ったとして
普通に書くと
if( kekka == 0 )
{
 printf( "大吉" );
}
else if( kekka == 1 )
{
 printf( "中吉" );
}
else if( kekka == 2 )
{
 printf( "小吉" );
}


と単純なif文が多くなってしまうと思うんですが、それをなるべく短く、かつ見やすく解決する方法って無いでしょうか?
ちなみにこの例だと配列を使えば解決するんですが、それ以外の方法を教えてほしいです。

たかぎ

Re:ifやswitchを使わない条件分岐について

#2

投稿記事 by たかぎ » 15年前

短くできるのは条件演算子ですが、決して見やすいとはいえません。
やはり配列にするのが一番では?

なんちゃってプログラマ

Re:ifやswitchを使わない条件分岐について

#3

投稿記事 by なんちゃってプログラマ » 15年前

お返事ありがとうございます。
確かに配列を使うと見やすく行くと思うのですが…。
srand( (unsigned int)time(NULL) );
char* s[5] = { "大吉" , "中吉" , "小吉" , "凶" , "大凶" };
printf( "%s\n" , s[ rand() % 5 ] );

この用に単純なプログラムだと良いのですが、C++での開発で
「もし、何々の時にオブジェクトを生成する」といった場合はどの様にしたら良いのでしょう?

製作しているゲームで、外部データを元にオブジェクトを生成させる処理があり、

// 登録されたデータ分生成
for( ; itr != DataContiner.end() ; ++itr )
{
 int type = (*itr).ObjType;
 if( (*itr).ObjType == WALL )
 {
  ObjectSPtr enemy( new Wall( 略 );
  mObjectManager.add( enemy );
 }
 if( (*itr).ObjType == WOODWALL )
 {
  ObjectSPtr enemy( new WoodWall( 略 );
  mObjectManager.add( enemy );
 }
 ~略(この様な処理が30個程…。)~
}

この様な処理になってしまい、非常に醜い(見にくい)です。

ファクトリーなどの導入も考えましたが、結局の所コードが同じ様な処理になってしまいどうにも参っています。

こういった場合、どうすれば簡潔にかけるでしょうか?

YuO

Re:ifやswitchを使わない条件分岐について

#4

投稿記事 by YuO » 15年前

素直に実装するなら,
class Object
{
public:
  virtual ObjectSPtr create_enemy() = 0;
};

class WallObject : public Object
{
public:
  ObjectSPtr create_enemy() { return new Wall(); }
};

class WoodWallObject : public Object
{
public:
  ObjectSPtr create_enemy() { return new WoodWall(); }
};
のような継承関係を作っておいて,
for( ; itr != DataContiner.end() ; ++itr ) {
  mObjectManager.add(itr->create_enemy());
}
のように処理することでしょうか。

どこか一箇所switch文かそれに相当するコードが必要になりますが,
それ以降は全部継承を使ってswitch文が不要になります。

なんちゃってプログラマ

Re:ifやswitchを使わない条件分岐について

#5

投稿記事 by なんちゃってプログラマ » 15年前

>YuOさん
Wallを生成するのにWallObjectと言うクラスに責任を預けると言う事でしょうか?

やはりクラス数が2倍になっても、ファクトリーの様なものを作ったほうがスマートに書けそうですね。
(というかそれ以外になさそう…w)

Justy

Re:ifやswitchを使わない条件分岐について

#6

投稿記事 by Justy » 15年前

>外部データを元にオブジェクトを生成させる処理があり、
 ObjTypeが整数・列挙型とかで、0から始まっているとするなら
[color=#d0d0ff" face="monospace]
enum Type { WALL, WOODWALL };
ObjectSPtr *CreateWall() { return new Wall(); }
ObjectSPtr *CreateWoodWall() { return new WoodWall(); }
[/color]

という関数を作っておいて
[color=#d0d0ff" face="monospace]
const std::pair<Type, ObjectSPtr* (*)()> CreateSptrTbl[/url] =
{
std::make_pair(WALL, CreateWall),
std::make_pair(WOODWALL, CreateWoodWall),
};
[/color]
というような(手抜きなので pairを使っていますが)テーブルを作ります。
 で、何の型かは不明ですが DataContinerをループで回すときに
[color=#d0d0ff" face="monospace]
for( ; itr != DataContiner.end() ; ++itr )
{
const Type type = (*itr).ObjType;
if(type >= 0 && type <sizeof(CreateSptrTbl) / sizeof(CreateSptrTbl[0]))
mObjectManager.add((*CreateSptrTbl[type].second)());
}
[/color]

とすればそれなりにすっきりはしますね。

 ObjTypeが整数・列挙型以外だったり、0から始まっているわけでないのなら
mapにでも入れて似たようなことができるかと思いますが、どうでしょう?

閉鎖

“C言語何でも質問掲示板” へ戻る