2011-07-23 73 views
25

使用throw new FoobarException(Baz argument);throw FoobarException(Baz argument);是否合适?C++:抛出异常,使用'新'或不?

捕捉时我总是使用catch(FoobarException& e)“以防万一”,但我从来没有找到一个坚实的答案,我是否必须在C++中使用新的或不使用(Java绝对)或者它只是程序员的偏好。

+2

我不认为它会赶上,如果你抛出指针,并试图通过引用赶上,是吗? –

+2

如果你使用new,那么'catch(FoobarException&)'不会捕获你的对象。新创建指针。 –

回答

33

C++中的异常应该由值引发,并通过引用来捕获。

因此,这是正确的方法:

try 
{ 
    throw FoobarException(argument); 
} 
catch(const FoobarException &ex) 
{ 
    cout << ex.what() << endl; 
} 

不要把新创建了一个例外,因为谁负责删除它没有明确定义。此外,在错误处理期间执行分配可能会引发另一个异常,从而模糊了原始问题。

你不需要通过const引用来捕获(非const将正常工作),但我喜欢无论如何这样做。但是,您应该始终通过引用(而不是通过值)来多态地捕获异常。如果你不这样做,异常的类型可能会被切割。

+0

为什么异常应该始终通过引用而不是按值来捕获?您是否因为将派生对象按值传递给方法期望基类对象的参数而提到对象切片问题? – Destructor

7

除非有一些特殊要求不要,我总是会抛出价值并被const赶上参考。这是因为在错误处理期间,new本身也可能引发异常,所以最好避免可能导致异常的事情。

+0

这是正确的,抛出一个异常,而另一个异常是活跃的基本上是禁止的(我认为它是UB),所以标准的'new'已经不存在了。你可以使用一些非抛出分配,如果你真的必须这样做,但这仍然是疯狂的:-) –

+1

我的2c的:只是添加到@KerrekSB的贤者的建议,它实际上是定义的行为(见http://en.cppreference .COM/W/CPP /错误/终止)。前面提到的链接还指出了许多其他最好避免的事情(例如从析构函数中抛出异常,因为那样当堆栈正在解开先前抛出的异常时,您可能会提起异常)。 – Rob