Comment stocker un vecteur d'objets LPD3DXSPRITE?
Question
Supposons que je souhaite stocker un vecteur d'objets LPD3DXSPRITE. La ligne pour déclarer ce code serait std::vector<LPD3DXSPRITE> sprites;
Je devrais pouvoir créer mon sprite avec:
LPD3DXSPRITE sprite = NULL;
D3DXCreateSprite(myRenderingDevice, &sprite);
Enfin, je devrais pouvoir ajouter ceci au vecteur comme suit:
sprites.push_back(sprite);
Au moins si j'ai bien compris, cela devrait être plausible. Cependant, cela compile mais donne des erreurs d'exécution. Pourquoi est-ce? Est-ce que j'y vais mal? Comment puis-je résoudre ce problème?
modifier:
Cela peut également être utile. La pile d’appel donne pour cette fonction ce qui est appelé vector<ID3DXSprite *, std::allocator<ID3DXSprite *>>::push_back(ID3DXSprite * const &_Val=0x0036fd38
. Ce n'est pas le vecteur qu'il a été transmis.
Cependant, LPD3DXSPRITE n’est qu’une typedef pour ID3DXSprite *. Cela pourrait-il apporter quelque chose à la lumière?
La solution
Après avoir parcouru votre code, j'ai trouvé le problème. Un élément à considérer lorsque vous rencontrez des interruptions dans votre application est l'option & "; Autos &"; onglet ou l'onglet Locaux. Ici, vous remarquerez quelque chose sur le this
pointeur: c'est null!
Cela signifie que l'instance sur laquelle AddSprite
est appelé n'existe pas. Ceci est votre SpriteManager
, que je vois est un singleton. Dans votre main, vous n'en créez pas une instance.
J'ai dû faire plusieurs choses pour que cela fonctionne. J'ai inclus "LudoRenderer/SpriteManager.h"
dans Main.cpp
et ajouté l'appel CreateInstance
:
SpriteManager::CreateInstance();
Le seul problème avec cela était que vous aviez déclaré votre constructeur / destructeur privé, comme d’autres singletons, mais ne les avez jamais définis, alors j’ai fait cela aussi:
SpriteManager::SpriteManager(){}
SpriteManager::~SpriteManager(){}
Après ces modifications, & "; a fonctionné &" ;. C'est entre guillemets parce que votre problème est résolu, mais il y a une autre erreur plus tard dans le code m_GameManager->SetWagon(m_Wagon);
.
Ici, m_GameManager
n'est pas initialisé. J'ai commenté m_GameManager = GameManager::GetInstance();
à la ligne 43 de LudoEngine.cpp
, ce qui nous place dans le même problème qu'auparavant, aucun ErrorLogger::LogError
n'est appelé. J'ai ajouté l'en-tête nécessaire dans main, appelé la méthode create. Cela a résolu le problème et votre moteur a démarré (une démo aussi!)
Il y a eu un blocage à la sortie, dans ErrorLogger
, car LudoMemory
était nul. On l'appelait dans le destructeur de GetInstance
, mais je vous laisse celui-ci. :)
Maintenant, deux astuces qui pourraient aider. Le premier concerne le problème que nous résolvons. Normalement, les singletons vont se créer s'ils ne le sont pas déjà. Je changerais votre singleton delete 0
en quelque chose comme ceci:
static T *GetInstance ( )
{
if (!m_Singleton) // or == NULL or whatever you prefer
{
CreateInstance();
}
return m_Singleton; // not sure what the cast was for
}
Ceci forcera la création du singleton si ce n'est déjà fait. Désormais, si vous souhaitez que les utilisateurs appellent LUDO_SAFE_DELETE
avant d'essayer <=>, vous pouvez ajouter une sorte d'avertissement:
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;
}
Etant donné que cela laisse de côté les informations importantes & "Quel singleton? &"; vous pouvez toujours essayer d'y ajouter un typeinfo:
#include <typeinfo>
// ...
std::cerr << "Warning, late creation of singleton: "
<< typeid(T).name() << std::endl;
Pour essayer d'y insérer des noms de types.
Enfin, <=> votre macro de suppression cochée n'est pas nécessaire.
Pour clarifier, vous avez <=>, qui vérifie si ce n'est pas nul avant d'appeler delete. En C ++, la suppression de null n'a pas d'effet, votre vérification n'est donc pas nécessaire. Toutes les occurrences de votre suppression sécurisée peuvent être remplacées par uniquement votre LUDO_DELETE.
Autres conseils
Le code me semble correct. Mais vous stockez un pointeur sur ID3DXSprite dans le vecteur. Comment cela est-il désaffecté? Est-il possible que l’image-objet ait été désaffectée afin que le vecteur tienne un pointeur non valide, puis tente de le référencer?