Как сохранить вектор объектов 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 - это просто typedef для ID3DXSprite *.Может ли это пролить что-нибудь на свет?
Решение
Просмотрев ваш код, я обнаружил проблему.На что следует обратить внимание при возникновении каких-либо сбоев в работе вашего приложения, так это на вкладку "Авто" или "Локальные".Здесь вы заметите кое-что о 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
когда-либо вызывался.Я добавил необходимый заголовок в main, вызвав метод create.Это устранило проблему, и ваш движок заработал (тоже классная демо-версия!).
На выходе произошла авария, в ErrorLogger::LogError
, потому что ErrorLogger
было равно нулю.Это было вызвано в LudoMemory
это деструктор, но я оставлю этот для тебя.:)
Теперь, я думаю, вам помогут два совета.Первый касается проблемы, которую мы решаем.Обычно синглтоны создаются сами по себе, если они еще не созданы.Я бы изменил твой синглтон 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
, который проверяет, не равно ли оно null, прежде чем вызвать delete.В C ++ удаление null не имеет никакого эффекта, поэтому ваша проверка не нужна.Все экземпляры вашего безопасного удаления могут быть заменены только вашим LUDO_DELETE.
Другие советы
На мой взгляд, код выглядит нормально.Но вы сохраняете указатель на ID3DXSprite в векторе.Как это распределяется?Возможно ли, что спрайт был удален, поэтому вектор в конечном итоге содержит недопустимый указатель, а затем пытается ссылаться на указатель?