5

到目前为止,我已经成功地完成了我的 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 合作的具体建议。

4

3 回答 3

19

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

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

于 2010-04-29T11:32:28.740 回答
6

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

于 2010-04-29T11:33:00.760 回答
6

您似乎不知道如何调试异常。任何一个

  • 调出 VS Debug/Exceptions 对话框并勾选 C++ Exceptions 框。这将使您有机会(出现一个对话框)在抛出异常时进行调试。

或者

  • 如果您已经构建了 Ogre 源代码,请在Ogre::Exception 构造函数中设置断点,当它尝试抛出一个断点时,您将中断一个调用堆栈,其中下一级是抛出站点。
于 2010-04-29T11:38:44.877 回答