LPD3DXSPRITE オブジェクトのベクトルを保存するにはどうすればよいですか?
質問
LPD3DXSPRITE オブジェクトのベクトルを保存したいとします。このコードを宣言する行は次のようになります。 std::vector<LPD3DXSPRITE> sprites;
次のようにしてスプライトを作成できるはずです。
LPD3DXSPRITE sprite = NULL;
D3DXCreateSprite(myRenderingDevice, &sprite);
最後に、次のようにこれをベクトルに追加できるはずです。
sprites.push_back(sprite);
少なくとも私の理解では、それはもっともらしいはずです。ただし、これはコンパイルできますが、実行時エラーが発生します。どうしてこれなの?私のやり方が間違っているのでしょうか?どうすれば直りますか?
編集:
これも役立つかもしれません。この関数の呼び出しスタックは次のようになります。 vector<ID3DXSprite *, std::allocator<ID3DXSprite *>>::push_back(ID3DXSprite * const &_Val=0x0036fd38
と呼ばれるものです。これは渡されたベクトルではありません。
ただし、LPD3DXSPRITE は ID3DXSprite * の typedef にすぎません。これで何か明らかになるでしょうか?
解決
コードを調べたところ、問題が見つかりました。アプリケーションで何らかの中断が発生したときに確認する必要があるのは、[Autos] タブまたは [Locals] タブです。ここで、あることに気づくでしょう。 this
ポインタ:それはヌルです!
つまり、 AddSprite
呼び出されているものは存在しません。これはあなたの SpriteManager
, 、これはシングルトンであることがわかります。メインでは、そのインスタンスを作成しません。
これを機能させるには、いくつかのことを行う必要がありました。含めました "LudoRenderer/SpriteManager.h"
で Main.cpp
, 、と追加しました CreateInstance
電話:
SpriteManager::CreateInstance();
これの唯一の問題は、他のシングルトンと同様に、コンストラクター/デストラクターをプライベートとして宣言していながら、それらを定義していなかったことでした。そのため、私もそれを行いました。
SpriteManager::SpriteManager(){}
SpriteManager::~SpriteManager(){}
これらの変更後、「機能」しました。問題は解決されているため、引用符で囲まれていますが、コードの後半に別のエラーがあります m_GameManager->SetWagon(m_Wagon);
.
ここ、 m_GameManager
初期化されていません。コメントを外しました m_GameManager = GameManager::GetInstance();
43行目で LudoEngine.cpp
, 、これは私たちを以前と同じ問題に陥らせます、いいえ CreateInstance
と呼ばれることがあります。create メソッドと呼ばれる必要なヘッダーを main に追加しました。これで問題が解決し、エンジンが動作しました (クールなデモも!)
出口で衝突事故があった ErrorLogger::LogError
, 、 なぜなら ErrorLogger
ヌルでした。呼び込まれていたのです LudoMemory
のデストラクタですが、これは残しておきます。:)
さて、役立つヒントを 2 つ挙げておきます。1つ目は、私たちが解決している問題についてです。通常、シングルトンがまだ作成されていない場合は、シングルトン自体が作成されます。シングルトンを変更します GetInstance
次のようなものに:
static T *GetInstance ( )
{
if (!m_Singleton) // or == NULL or whatever you prefer
{
CreateInstance();
}
return m_Singleton; // not sure what the cast was for
}
これにより、シングルトンがまだ作成されていない場合は強制的に作成されます。ここで、ユーザーに電話をかけたい場合は、 CreateInstance
しようとする前に GetInstance
, 、何らかの警告を追加できます。
static T *GetInstance ( )
{
if (!m_Singleton) // or == NULL or whatever you prefer
{
CreateInstance();
std::cerr << "Warning, late creation of singleton!" << std::endl;
// or perhaps:
ErrorLogger::GetInstance()->
LogError(L"Warning, late creation of singleton!");
}
return m_Singleton;
}
これでは「どのシングルトンか?」という重要な情報が省略されているため、いつでも typeinfo を追加してみることができます。
#include <typeinfo>
// ...
std::cerr << "Warning, late creation of singleton: "
<< typeid(T).name() << std::endl;
そこにいくつかの型名を取得しようとします。
そして最後に、大丈夫です delete 0
, の場合、チェックした削除マクロは必要ありません。
明確にするために、あなたは持っています LUDO_SAFE_DELETE
, これは、delete を呼び出す前に null でないかどうかをチェックします。C++ では、null を削除しても効果がないため、チェックは必要ありません。安全な削除のすべてのインスタンスは、LUDO_DELETE のみで置き換えることができます。
他のヒント
コードは私には問題ないようです。 ただし、ID3DXSpriteへのポインターをベクターに格納しています。これはどのように割り当て解除されますか? スプライトの割り当てが解除されて、ベクターが無効なポインターを保持し、ポインターを参照しようとする可能性はありますか?