0
class GameBoy{

  public:
    GameBoy()
      :cart(new Cartridge()),
        mmu(new MMU(cart)),
        cpu(new CPU(mmu))
    {}

    void step(); //steps through one instruction
    const CPU::State &getCPUState() const noexcept;
    void loadROM(std::string fileName);

  private:
    std::shared_ptr<Cartridge> cart;
    std::shared_ptr<MMU> mmu;
    std::shared_ptr<CPU> cpu;

  };

私はゲームボーイエミュレーターを書いています.このクラスはQt GUIがインターフェースするものです. つまり、GUI で描画されるフレームごとに、GameBoy::step() が呼び出されます。まだ GPU の作業を開始していないため、明らかに完成していません。

これらの 3 つのクラス (カートリッジ、CPU、MMU) は 1 回だけインスタンス化されるため、現在この設計について質問しています。シングルトンはこれよりも優れた設計でしょうか、それとも現在の設計が最適でしょうか?

これが最適な場合、shared_ptr を使用する必要がありますか? 慎重に使用する必要があると読んだことがありますが、ここでは、3 つのクラスすべてが相互に依存しているため、理にかなっているようです。

どうもありがとうございました!

編集:人々は、なぜポインタを使用しているのかと尋ねています。init リストからわかるように、MMU にはカートリッジへの参照が必要であり、CPU には MMU への参照が必要です。

カートリッジは、GameBoy::loadROM() およびほとんどの MMU メソッドで使用されます。MMU はゲームボーイが所有する必要はないかもしれませんが、CPU と GPU の間で共有されることに同意します (私はそう思います)。

以下の例では、カートの共有ポインターに代わるより良い方法はありますか?

クラス間の使用例:

byte MMU::readByte(word address) {
            ....
            value = cart->readROM(address);
            ....
        }

void GameBoy::loadROM(std::string fileName){
            cart->loadROM(fileName);
}

編集 2: みんなありがとう! 最後に 1 つ質問があります。GPU と CPU の両方が MMU を使用し、ゲームボーイが GPU と CPU の両方を使用する場合、どちらの設計が優れているか:

class GameBoy{

public:
GameBoy()
 : CPU(&mmu), gpu(&mmu)
...

private:
MMU mmu;  //never used by GameBoy
CPU cpu;  //CPU and GPU used in GameBoy
GPU gpu;

};

class CPU{
...

private:
MMU *mmu;
};

class GPU{

...

private:
MMU *mmu;

};

また:

class GameBoy{

public:
GameBoy()
 : CPU(), gpu(&cpu.getMMU())
...

private:
CPU cpu; //CPU and GPU used in GameBoy
GPU gpu;

};

class CPU{
...

private:
MMU mmu;  //arbitrarily chosen owner.  GPU could have been the owner
};

class GPU{

...

private:
MMU *mmu;

};

一貫性があるように見えるので、最初のものの方が少し好きですが、GameBoy は MMU を使用しません。

4

4 に答える 4

0

変化は絶え間なく起こります。コードを変更したくなる時が来ると確信する必要があります。つまり、現在の設計でシングルトンが必要ない場合は、シングルトンに限定する理由はありません。現在の実装では、より多くの拡張性が可能です。

に関しては、同じ共有インスタンスshared_ptrへの複数のポインタが必要な場合に使用します。たとえば、 と の 3 つのクラスがあるとします。とは両方とも のインスタンスへのポインタを持ち、1 つのインスタンスは と の間で共有されるため、両方とが削除された後にのみ削除する必要があります。その例では、を使用する必要があります。それ以外の場合は、を使用する必要があります。したがって、使用しないでください。実際、とがインターフェース/基本クラスではなく具象クラスである場合は、いかなる種類のポインターも使用しないでください。ABCBCABC BCshared_ptrunique_ptrshared_ptrcartmmucpu

編集:

GameBoyクラスが CartridgeMMUおよびのインスタンスを必要とするのはなぜCPUですか? CPU独自のMMUを作成する が独自の を作成するだけではないのはなぜCartridgeですか?

于 2013-08-19T02:27:31.100 に答える