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 を使用しません。