【问题标题】:How to store a vector of LPD3DXSPRITE objects?如何存储 LPD3DXSPRITE 对象的向量?
【发布时间】:2009-11-26 21:13:35
【问题描述】:

假设我想存储 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。这能揭示什么吗?

【问题讨论】:

  • 什么是运行时错误?
  • 内存访问冲突。它在向量类的 size() 函数处中断。
  • 您在检查 D3DXCreateSprite 调用的结果吗?
  • 这很可能是您对向量的操作。您的代码对我来说看起来不错,我知道我也这样做了。什么代码使用了向量?
  • @GMan,还没有。所有使用它的代码都被注释掉了。我所做的就是将这个精灵推入向量中。这真的让我难以置信。

标签: c++ vector directx


【解决方案1】:

查看您的代码后,我发现了问题。当您在应用程序中遇到任何中断时要查看的内容是“Autos”选项卡或“Locals”选项卡。在这里,您会注意到this 指针的一些内容:它是空的!

这意味着正在调用AddSprite 的实例不存在。这是你的SpriteManager,我看到它是一个单身人士。在您的主目录中,您不会创建它的实例。

我必须做几件事才能让它工作。我将"LudoRenderer/SpriteManager.h" 包含在Main.cpp 中,并添加了CreateInstance 调用:

SpriteManager::CreateInstance();

唯一的问题是你已经将你的构造函数/析构函数声明为私有,就像其他单例一样,但从未定义它们,所以我也这样做了:

SpriteManager::SpriteManager(){}
SpriteManager::~SpriteManager(){} 

在这些更改之后,它“工作”了。那是在引号中,因为您的问题已解决,但代码m_GameManager->SetWagon(m_Wagon); 后面还有另一个错误。

这里,m_GameManager 未初始化。我在LudoEngine.cpp 的第43 行取消了m_GameManager = GameManager::GetInstance(); 的注释,这使我们遇到了与以前相同的问题,从未调用过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
}

如果还没有创建单例,这将强制创建。现在,如果您希望用户在尝试拨打GetInstance 之前先拨打CreateInstance,您可以添加某种警告:

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,它在调用删除之前检查它是否不为空。在 C++ 中,删除 null 无效,因此不需要您的检查。安全删除的所有实例都可以只替换为您的 LUDO_DELETE。

【讨论】:

  • 惊人的细节。非常感谢。非常有用的提示,以及。关于您的编辑,我不确定我是否理解您所说的可以删除 0 的意思。
  • "ok to delete 0" 表示您可以在 NULL 指针上调用 delete 并且不会发生任何错误 (discuss.joelonsoftware.com/default.asp?design.4.194233.15)
【解决方案2】:

代码在我看来没问题。 但是您将指向 ID3DXSprite 的指针存储在向量中。这是如何取消分配的? 是否有可能精灵已被取消分配,因此向量最终持有无效指针,然后尝试引用该指针?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多