繁体   English   中英

C++中通过指针捕获异常

[英]catch exception by pointer in C++

我发现有3种方法可以捕获异常,有什么区别?

1) 按价值捕获;

2)按引用捕获;

3) 指针捕捉;

我只知道按值捕获会调用对象的两个副本,按引用捕获会调用一个。 那么如何通过指针捕获呢? 什么时候使用指针捕获? 除了抛出一个对象,我还能像这样抛出一个指向对象的指针吗?

class A {}

void f() {

  A *p = new A();
        throw p;


}

推荐的方法是按值抛出并按引用捕获

您的示例代码抛出一个指针,这是一个坏主意,因为您必须在捕获站点管理内存。

如果你真的觉得你应该抛出一个指针,使用一个智能指针,比如shared_ptr

无论如何,Herb Sutter 和 Alexei Alexandrescu 在我转述的他们的 C++ 编码标准书中很好地解释了这一点。

请参阅C++ 编码标准:按值抛出,按引用捕获

Catch 遵循正常的赋值兼容性规则,即如果抛出一个值,则可以将其作为值或引用捕获,但不能作为指针捕获; 如果您抛出一个指针,则只能将其作为指针(或对指针的引用...)捕获。

但是抛出指针并没有真正的意义,它只会导致内存管理头疼。 因此,您通常应该遵循规则throw by value, catch by reference ,正如 Gregory 所解释的那样。

Microsoft 的 MFC 使用按指针捕获,但我认为这是为了在正确实现 try 和 catch 之前与编译器兼容; 最初他们使用 TRY 和 CATCH 宏来模拟它。 每个异常都派生自CException,它有一个方法来判断对象是否需要被删除。

我不建议将其用于任何现代异常设计。 通过引用捕获是要走的路。

虽然基本上可以抛出任何类型的任何对象,但这样做几乎没有(如果有的话)。 动态分配主要在对象需要具有生命周期而不适合自动分配时有用——即您希望它的生命周期独立于正常程序范围。

然而,在异常对象的情况下,这并没有多大意义。 异常对象通常仅在异常处理程序内部使用,并且您显然希望在退出该异常的(最后一个)处理程序时销毁它。

还有一个事实是,您通常希望异常处理代码相当简单。 例如,如果您试图报告空闲存储/堆已耗尽或损坏,则尝试将异常对象从耗尽/损坏的空闲存储/堆中分配通常不会很好地工作......

通过指针捕获/抛出异常并不是一个很好的场景。 C++ 语义允许这样做,但它并不是非常有用,因为大多数情况下您将抛出一个临时异常或字符串对象。

然而,一些库(Boost.Graph 这样做,我相信)使用 throw 将返回值从深度递归函数传递回调用者; 在这种情况下,返回值可能是一个指针,所以抛出一个指针是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM