私のコードには、ゲームのすべてのサウンドを格納して操作する SoundManager クラスがあります。このクラスはインスタンス化する必要があり、他の複数のクラスによって呼び出されるメソッドです。ただし、メモリを占有するサウンドのセットを 1 つだけにしたいので、効率を高めるために、すべてのアセットを static shared_ptrs として宣言します。
#include "SoundManager.h"
static shared_ptr<ISoundEngine> sEngine;
static shared_ptr<ISoundSource> hoverSound;
static shared_ptr<ISoundSource> confirmSound;
static shared_ptr<ISoundSource> mainBGM;
static shared_ptr<ISound> bgmInterface;
SoundManager::SoundManager(void)
{
//first we need to create the irrKlang sound engine instance
if(!sEngine)
{
sEngine.reset(createIrrKlangDevice());
}
if(!hoverSound)hoverSound.reset(sEngine->addSoundSourceFromFile("Sounds/ButtonHover.mp3"));
if(!confirmSound)confirmSound.reset(sEngine->addSoundSourceFromFile("Sounds/ButtonConfirm.mp3"));
if(!mainBGM)mainBGM.reset(sEngine->addSoundSourceFromFile("Sounds/mainBGM.mp3"));
//set some default volumes
hoverSound->setDefaultVolume(1.0f);
confirmSound->setDefaultVolume(0.4f);
mainBGM->setDefaultVolume(0.5f);
}
SoundManager::~SoundManager(void)
{
}
このSoundManagerはmain()関数でインスタンス化され、タイトル画面をロードする必要があるたびにインスタンス化されます(SoundManagerはこのtitlescreenクラスでもインスタンス化されます)。タイトル画面の初期化と破棄を繰り返しても問題はありません。静的な shared_ptrs オブジェクトは、SoundManager のメイン関数インスタンスによってまだ使用されているため、破棄されません。
これで、ゲームを実行するために実際に問題なく動作します。ただし、きれいに終了する場合、上記の静的オブジェクトが解体されると、未処理のランタイム例外 (アクセス違反) がスローされます。VS2012 のデバッガーが memory.h の行を指しています。
private:
virtual void _Destroy()
{ // destroy managed resource
delete _Ptr; <<<<<<<<<The debugger points to this line
}
obj-c と同様に、c++ の shared_ptrs は参照カウンターを使用して、使用が必要なオブジェクトが存在しなくなるまでオブジェクトが削除されないようにすることを理解する必要がありました。これらのエラーの原因がわかりません。
省略してはいけない重要な部分かもしれませんが、私のゲームは exit(0) の呼び出しによって終了しています。できるだけ main() 関数に近づけます。これを行う前に、SoundManagers メンバーをクリーンアップするための何らかのアクションを実行していません。
クリーンアップの問題の原因を誰か知っていますか?