Вопрос

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top