Как сохранить вектор объектов LPD3DXSPRITE? - PullRequest
2 голосов
/ 27 ноября 2009

Допустим, я хочу сохранить вектор объектов 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 *. Может ли это принести что-нибудь на свет?

Ответы [ 2 ]

3 голосов
/ 27 ноября 2009

После просмотра вашего кода я обнаружил проблему.Когда вы получаете какие-либо перерывы в своем приложении, вам стоит обратить внимание на вкладку «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 никогда не вызывается.Я добавил необходимый заголовок в 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, который проверяет, не является ли он нулевым, прежде чем вызывает delete.В C ++ удаление нуля не имеет никакого эффекта, поэтому ваша проверка не нужна.Все экземпляры вашего безопасного удаления могут быть заменены только вашим LUDO_DELETE.

0 голосов
/ 27 ноября 2009

Код выглядит нормально для меня. Но вы храните указатель на ID3DXSprite в векторе. Как это распределяется? Возможно ли, что спрайт был перераспределен, поэтому вектор в итоге содержит недопустимый указатель, а затем пытается обратиться к указателю?

...