C++构造函数中捕获异常

7

当使用异常时,我如何保护自己免受使用未完全创建的对象的影响? 我应该在构造函数中捕获吗? 或者这是不好的实践? 如果我在构造函数中捕获,对象将被创建。

#include <stdio.h>

class A
{
public:
    A()
    {
        try {
            throw "Something bad happened...";
        }
        catch(const char* e) {
            printf("Handled exception: %s\n", s);
        }
        // code continues here so our bad/broken object is created then?
    }
    ~A() 
    { 
        printf("A:~A()"); 
    }

    void Method()
    { // do something
    }
};

void main()
{
    A object; // constructor will throw... and catch, code continues after catch so basically we've got 
              // broken object.

    //And the question here: 
    //
    //* is it possible to check if this object exists without catching it from main? 
    // &object still gives me an address of this broken object so it's created but how can I protect myself 
    // from using this broken object without writing try/catch and using error codes?
    object.Method(); // something really bad. (aborting the program)

};

你为什么要对自己施加完全随意的限制? - Benjamin Lindley
3个回答

9
语言本身没有任何可检测的方式来表明对象是否“无效”。如果异常表示无法创建有效对象,则不应在构造函数中处理它;要么重新抛出它,要么一开始就不要捕获它。然后程序将离开正在创建的对象的作用域,不可能错误地访问它。
如果由于某种原因这不是一个选项,那么您需要自己的方法将对象标记为“无效”;也许在构造函数末尾设置一个布尔成员变量以指示成功。这种方法不可靠且容易出错,所以除非有非常好的理由,否则不要这样做。

谢谢,这就是我想知道的。 - user3841735

2

如果在特定异常被抛出时对象处于无效状态,那么我会让异常解开调用堆栈,以便通知调用者(从而做出反应)。

但是,如果异常可以从中恢复,那么根据您的应用程序可能值得尝试。不过请确保使用诸如记录器甚至简单的 stderr 来指示正在发生这种情况。


1
我将建议进行第一次迭代,更像这样做:
   try {
        throw "Something bad happened...";
    }
    catch(const std::exception e) {
        cerr << e.what () << endl ; // Better off in the main
        throw ;
    }

这里有两件事情:

  1. 除非你的异常处理程序处理了异常,否则它应该抛出异常。

  2. 始终使用基于std::exception的异常类,以便您始终可以找出问题所在,如上所示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接