|
1
7
在以前的答案中没有清楚地写出来,所以: 异常发生在C++中使用stl或not不会删除raii代码,该代码将释放您分配的对象资源。 例如:
在上面的代码中,编译器将生成代码以释放mystring资源(即,将调用mystring析构函数),无论同时发生什么,包括如果dosomethingelse引发了异常,或者如果在函数范围结束之前执行了“返回”。 如果你对此有问题,那么要么你应该改变你的思维方式,要么试试C。 例外应该是例外通常,当发生异常时( and only when ,你会有一个性能冲击。 但是,只有在以下情况下才应发送异常:
这里的关键字是“exception”,这很好,因为我们正在讨论“exception”(见模式?). 在您的情况下,如果抛出了异常,那么很有可能是好的事情发生了,所以坏的事情发生了,您的程序无论如何都会毫无异常地崩溃。 在这种情况下,您的问题不是处理性能问题。它是处理错误的优雅处理,或者更糟的是,程序的优雅终止(包括一个“抱歉”消息框,将未保存的数据保存到一个临时文件中以便以后恢复,等等)。 这意味着(除非在非常特殊的情况下),不要将异常用作“返回数据”。当非常糟糕的事情发生时抛出异常。只有当你知道如何处理这个问题时,才能捕获一个异常。避免尝试/捕获(除非您知道如何处理异常)。 STL怎么样?现在我们知道了:
我们应该讨论STL: STL通常会(如果可能的话)验证你是否做错了。如果你这样做,它会抛出一个异常。不过,在C++中,你通常不会为你不使用的东西付费。 例如,访问向量数据。 如果你 知道 你不会越界,那么你应该使用操作符[]。 如果你 知道 您将不验证边界,然后应该使用()处的方法。 例A:
实例B:
示例A“信任”程序员,并且在验证过程中不会浪费时间(因此,引发异常的可能性更小) 那时 如果仍然有错误…这通常意味着错误/异常/崩溃通常会在之后发生,这对调试没有帮助,并且会让更多的数据损坏)。 示例B要求向量验证索引是否正确,如果不正确则抛出异常。 选择权属于你。 |
|
|
2
28
通常,STL容器自己抛出的唯一例外是std::bad_c alloc(如果new失败)。只有在其他时间,用户代码(例如构造函数、赋值、复制构造函数)抛出。如果你的用户代码从来没有抛出,那么你只需要防止新的抛出,这是你最有可能不得不做的。 其他可能引发异常的事情: -at()函数可以将std::抛出\u范围之外,如果您超出界限访问它们。无论如何,这是一个严重的程序错误。 其次,例外并不总是缓慢的。如果您的音频处理中发生异常,可能是因为您无论如何都需要处理一个严重的错误。错误处理代码可能比将异常传输到catch站点的异常处理代码要贵得多。 |
|
3
8
如果一个STL容器抛出,您可能会遇到比减速更大的问题:) |
|
|
4
3
不要害怕业绩方面的例外。 在过去的C++中,启用异常的构建在某些编译器上可能会慢很多。 这些天,不管您的构建是否有异常处理,它都是无关紧要的。 一般来说,除非内存不足,否则STL不会抛出异常,因此对于您的应用程序类型来说,这也不应该是问题。 (现在不要使用gc…..语言) |
|
|
5
3
值得注意的几点是:
我建议您接受STL及其例外情况(除非STL本身证明太慢-但请记住: 先测量,后优化 )以及在应用程序中对自己的“异常情况”(音频硬件故障,无论什么)采用异常处理。 |
|
|
6
1
我正在努力思考STL的哪些部分指定了它们可以引发异常。根据我的经验,大多数错误处理都是通过返回代码来处理的,或者作为STL使用的先决条件。
传递给STL的对象肯定会引发异常,例如复制构造函数,但不管使用STL,这都是一个问题。
其他人提到了诸如
当然,STL的特定实现可以执行“检查”,通常对于调试构建,在您使用STL的基础上,我认为它只会引发断言,但可能有些会抛出异常。 如果不存在try/catch,我相信除非您自己的类引发异常,否则不会发生任何/最小的性能损失。
在VisualStudio上,可以完全禁用C++异常的使用
|
|
|
7
0
你说话的时候好像免责是不可避免的。只是不要做任何可能导致异常的事情——修复错误,验证输入。 |