一般来说,STL容器自身抛出的唯一异常是std::bad_alloc,如果new失败的话。唯一的其他情况是用户代码(例如构造函数、赋值、拷贝构造函数)抛出异常。如果您的用户代码从不抛出异常,则只需防范new抛出异常,这通常是必须要做的。
还可能抛出异常的内容有: - at()函数可能会在越界时抛出std::out_of_range异常。无论如何,这都是一个严重的程序错误。
其次,异常并不总是很慢。如果在音频处理过程中发生异常,那么这可能是由于严重错误引起的,您肯定需要处理。错误处理代码可能比传输异常到catch点的异常处理代码显着昂贵。
之前的回答没有清楚地说明,因此:
无论使用 STL 还是不使用,都无法消除 RAII 代码,该代码将释放您分配的对象资源。
例如:
void doSomething()
{
MyString str ;
doSomethingElse() ;
}
typedef std::vector<std::string> Vector ;
void outputAllData(const Vector & aString)
{
for(Vector::size_type i = 0, iMax = aString.size() ; i != iMax ; ++i)
{
std::cout << i << " : " << aString[i] << std::endl ;
}
}
例子 B:
typedef std::vector<std::string> Vector ;
void outputSomeData(const Vector & aString, Vector::size_type iIndex)
{
std::cout << iIndex << " : " << aString.at(iIndex) << std::endl ;
}
at()
,然后再将at
优化为[]
。很多时候代码并不是性能关键,最好保险起见。 - Elazar Leibovich[]
,但我想你是对的。如果只是为了语法糖,没有理由不使用at()
。 - paercebal不要因为性能问题而害怕异常。
在C++的早期版本中,启用异常处理可能会使某些编译器变得非常缓慢。
如今,在你选择启用或禁用异常处理时,对于性能并没有什么影响。
通常情况下,STL不会抛出异常,除非内存耗尽,因此这对于你的应用程序类型也不应该是一个问题。
(现在别使用带有GC的语言了.....)
有几点需要注意:
你的应用程序是多线程的。如果一个线程(可能是GUI线程)因为异常而变慢,它不应该影响实时线程的性能。
异常是为了特殊情况而设计的。如果在你的实时线程中抛出异常,很可能意味着你无法继续播放音频。如果你发现无论什么原因都在这些线程中不断处理异常,那么重新设计以避免首先出现异常。
我建议你接受STL及其异常(除非STL本身证明太慢 - 但请记住:先测量,后优化),并在你的应用程序中采用异常处理来处理自己的“特殊情况”(例如音频硬件故障等)。
我很难想到STL的哪些部分指定了它们可以引发异常。在我的经验中,大多数错误处理都是通过返回代码或作为STL使用的先决条件来处理的。
传递给STL的对象肯定会引发异常,例如复制构造函数,但无论是否使用STL,这都将是一个问题。
其他人提到了诸如std::vector::at()
之类的函数,但通常可以执行检查或使用替代方法来确保不会抛出任何异常。
当然,STL的特定实现可以对您使用STL进行“检查”,通常用于调试构建,我认为它只会引发断言,但也许有些会引发异常。
如果没有try/catch存在,我相信除非您自己的类引发异常,否则不会产生任何/最小的性能损失。
在Visual Studio上,您可以完全禁用使用C++异常,请参见项目属性-> C/C++-> 代码生成-> 启用C++异常
。我认为这在大多数C++平台上都可用。
你说话的口气好像异常情况是不可避免的。只要不做可能会导致异常的事情——修复你的错误,验证你的输入。
new (std::nothrow)
更简单。无需再次编写内存分配器,这不是他的错... - Elazar Leibovich