【问题标题】:Is Ogre's use of Exceptions a good way of using them?Ogre 对异常的使用是一种使用它们的好方法吗?
【发布时间】:2010-04-29 11:24:55
【问题描述】:

到目前为止,我已经成功地完成了我的 C++ 游戏编程生涯,几乎从未接触过异常,但最近我一直在使用 Ogre 引擎开发一个项目,并且我正在努力学习。我在这里找到了很多关于 C++ 异常的一般用法的好问题和答案,但我想从这里获得一些关于 Ogre 的用法是否良好以及如何最好地使用它们的外部意见。

首先,引用 Ogre 自己的 Exception 类的文档:

OGRE 从不使用返回值来指示错误。相反,如果发生错误,则会引发异常,这是封装问题细节的对象。使用 OGRE 的应用程序应始终确保捕获异常,因此所有 OGRE 引擎函数都应发生在 try{} catch(Ogre::Exception& e) {} 块中。

真的吗?每个 Ogre 函数都可能抛出异常并被包裹在 try/catch 块中?目前,在我们使用它时,这是通过 main 中的 try/catch 来处理的,它将在退出之前显示一个带有异常描述的消息框。这对于调试来说可能有点尴尬,因为你没有得到堆栈跟踪,只有抛出错误的函数——更重要的是我们代码中调用 Ogre 函数的函数。如果它是 Ogre 代码中的断言,那么它将直接转到调试器中的代码,我将能够更容易地找出发生了什么 - 我不知道我是否遗漏了一些可以让我已经调试异常了吗?

我现在开始在我们的代码中添加更多的 try/catch 块,通常考虑是否 Ogre 函数抛出异常是否重要。如果它会停止一切工作,那么让主 try/catch 处理它并退出程序。如果它不是很重要,那么在函数调用之后立即捕获它并让程序继续。最近的一个例子是为应用于实体的材质构建顶点/片段程序参数的向量 - 如果材质没有任何参数,那么它会抛出异常,我捕捉到它然后忽略它没有不需要添加到我的参数列表中。这似乎是一种合理的处理方式吗?非常感谢任何与 Ogre 合作的具体建议。

【问题讨论】:

    标签: c++ exception visual-studio-2005 ogre3d


    【解决方案1】:

    您不需要将每次对 Ogre 的最后调用都包含在 try { ... } catch 中。只要您可以有意义地处理异常,您就可以这样做。在某些情况下,这可能在单个调用站点,或者它可能在某种高级循环中。如果你无法在任何地方有意义地处理它,那就不要抓住它;让调试器接管。

    特别是,您不应该在 main() 中捕获异常,原因正是您引用的原因(至少,不是在开发期间;您应该在生产中)。

    【讨论】:

    • +1 表示“只要你能有意义地处理异常”
    • 那么有意义地处理异常是否适用于我最后一个查找参数的示例?只要在异常之前没有进行任何修改,那么它就不会引起任何问题。 timday 指出了如何在抛出异常时对其进行调试,这将有很大帮助,如果我在调试模式下取出主要的 try/catch,如果没有捕获到异常会发生什么?
    • 当没有捕获到异常时,调试器会捕获它,并显示它是从哪里抛出的。
    • @identitycrisisuk:当然,你有权丢弃任何你想要的异常,只要它对你的应用程序的状态有意义。请记住,异常是昂贵的,因此您不希望它们以帧速率发生。但如果是在渲染资源的配置过程中,应该没什么大不了的。未捕获的异常被调试器捕获;应该就好像在抛出异常的点设置了断点(完整的堆栈跟踪、检查变量和堆栈帧等)。
    • @Marcelo 谢谢,这解决了我所有的问题。我将在调试模式下删除主要的 try/catch,但将其留在那里等待发布,所以它就像一个崩溃捕获器对话框。我认为我可以处理发生的一个异常,但是将来我会尝试修复它的来源,而不是让它在运行时发生。
    【解决方案2】:

    恐怕我对 Ogre 一无所知,但异常处理的一般规则是您尽可能从抛出站点捕获异常,但不要再进一步了。但是,这只有在引发异常的代码使用 RAII 来管理分配的资源时才有可能。如果代码使用对普通指针的动态分配或其他形式的手动资源管理,那么您需要在调用站点使用 try-blocks。如果是这种情况,我会说使用异常是个坏主意。

    【讨论】:

    • 我认为从资源分配的角度来看,Ogre 大部分都可以,它大部分都使用它自己的共享指针类(尽管他们不建议你重用......),你可以离开它一旦你不再使用东西就清理干净。
    【解决方案3】:

    您似乎不知道如何调试异常。 要么

    • 调出 VS 调试/异常 对话框并勾选 C++ Exceptions 盒子。这会给你一个 机会(出现一个对话框)进行调试,当 抛出异常。

    • 如果你已经构建了 Ogre 源,设置一个 Ogre::Exception 中的断点 构造函数,当它试图抛出一个你会打破 一个调用堆栈,下一级是 throw 站点。

    【讨论】:

    • 非常感谢,我知道会有一些东西,但找不到。也应该想到构造函数断点。
    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 2021-01-29
    • 2010-12-29
    • 1970-01-01
    • 2019-04-25
    • 2021-08-30
    • 2015-09-02
    • 2017-06-14
    相关资源
    最近更新 更多