enumとクラスを対応させる?

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

enumとクラスを対応させる?

#1

投稿記事 by おっぺけ » 3年前

はじめまして。
DXライブラリを使って簡単なシューティングゲームを作ろうと思っています。
(現在は設計を考えている段階で、まともに動くものはまだありません)

現在、自機が弾を発射する部分の設計をしており、
以下の様に作成しました。

コード:

#include <vector>

enum class BulletKind
{
	TypeA,
	TypeB
};

class BaseBullet
{
private:
	float angle, speed;

public:
	BaseBullet() {};
};

class BulletA : public BaseBullet
{
public:
	BulletA() {};
};

class BulletB : public BaseBullet
{
public:
	BulletB() {};
};

class BulletMgr
{
private:
	std::vector<BaseBullet*> m_bullet;

public:
	// 弾の発射
	void Shoot(BulletKind kind)
	{
		// Bulletの種類が増えるにつれ、以下の処理が長くなる
		switch (kind)
		{
		case BulletKind::TypeA: {
			BulletA* a = new BulletA();
			m_bullet.push_back(a);
			break;
			}

		case BulletKind::TypeB: {
			BulletB* b = new BulletB();
			m_bullet.push_back(b);
			break;
			}
		}

		// いろいろ~
	}
};
(必要分のみ記載しています)

弾を発射する際は、BulletMgrのShoot関数を使用し
BulletMgrクラスで全部の弾を管理するような仕組みにしようと思っています。
ただし、弾は複数種類用意したいので、弾のクラスをそれぞれ作っています(BulletA, BulletB)

そこで、質問なのですが、上記のコードではswitch文でそれぞの弾のインスタンス(?)を作成していますが、
この方法だと弾の種類が増えた場合(BulletC, BulletDなど)どんどんcase文が増えていき、増やすたびに手動でcase文を追加しないといけません。
上記のkindの種類によって、生成するクラスを変える方法(?)や、もしくは他に適切な方法があれば、
ご教授頂きたくお願い致します。

使用環境
・windows10
・visual studio 2019

参照魚
記事: 109
登録日時: 6年前

Re: enumとクラスを対応させる?

#2

投稿記事 by 参照魚 » 3年前

残念ながら本質的に解決方法はありません。関数にまとめたり、コード上で見易くするなどはありますが、工夫の範疇でしかないです。必ずkindの増加に応じて列挙する部分は残ります。その部分の視認性と記述性をよくするのがベターだと思います。

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: enumとクラスを対応させる?

#3

投稿記事 by あたっしゅ » 3年前

kindの種類によって、生成するクラスを変える方法

コード:

//
//
//
#include <iostream>
#include <iomanip>
#include <vector>

#include <vector>

enum class BulletKind
{
	TypeA,
	TypeB
};

class BaseBullet
{
private:
	float angle, speed;

public:
	BaseBullet() {};
	  
    virtual BaseBullet * copy () = 0;
};

class BulletA : public BaseBullet
{
public:
	BulletA() {
        std::cout << "BulletA" << std::endl;
	};

	virtual BaseBullet * copy ()
    {
        return new BulletA();
    };
};

class BulletB : public BaseBullet
{
public:
	BulletB() {
	    std::cout << "BulletB" << std::endl;
	};

	virtual BaseBullet * copy ()
    {
        return new BulletB();
    };
};

class BulletMgr
{
private:
    std::vector<BaseBullet*> m_base;
	std::vector<BaseBullet*> m_bullet;

public:
    BulletMgr ()
    {
        m_base.push_back (new BulletA ());
        m_base.push_back (new BulletB ());
    }

	// 弾の発射
	void Shoot(BulletKind kind)
	{
    	BaseBullet* a = m_base[ (int)kind ]->copy();
    	m_bullet.push_back( a );


		// いろいろ~
	}
};


int
main()
{
	std::cout << "m_base" << std::endl;
    BulletMgr bm;
    
	std::cout << "m_bullet" << std::endl;
    bm.Shoot( BulletKind::TypeA );
    bm.Shoot( BulletKind::TypeB );
    bm.Shoot( BulletKind::TypeA );
    bm.Shoot( BulletKind::TypeB );
    
    return 0;
}


// end.
東上☆海美☆「これでどうでしょう」
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

返信

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