如何检查对象构造是否完整?

时间:2009-02-01 19:01:36

标签: c++

有一个带有几个整数和一个指针的类,

 class A {
     int a;
     int b;
     char* s;
    public:
    ...
      class ConstructA {
           A &a;
           public:
           ConstructA (A& ta) : a(ta) {}
           ...

      };

};

如上所见,ConstructA负责构建对象A. 我想编写一个方法来查看ConstructA是否成功构造了对象a。你会怎么做呢?

5 个答案:

答案 0 :(得分:7)

由于构造函数无法在C ++中失败,因此对象可以是:

  • 不存在
  • 已成功构建。

如果构造函数抛出异常,则在捕获异常时该对象实际上不存在。

您可能希望实现一个额外的方法,例如isOK(),它返回对象的内部状态是否表示有用的东西。例如,如果您有一个表示文件的对象,则可以使用isOK()表示该文件可以成功打开。但是,就C ++而言,无论文件是否可以打开,文件对象都将完全构建。

话虽如此,我并不完全确定ConstructA类在你的例子中的作用。

答案 1 :(得分:0)

作为一般规则,如果构造中存在任何失败,您将获得抛出异常 - 来自对象本身的特定于程序的异常,或者来自运行时的内存异常或类似内容。

在这种特殊情况下,您没有构建类型为A的对象,而是要初始化引用。所以没有任何建筑有失败的机会。

(也许关于你想要完成什么的更多细节可以帮助有人给出更好的答案?)

答案 2 :(得分:0)

首先,你的ConstructA课对我来说毫无意义。基本上确实有两种情况:

  1. 对象的构造失败
  2. 对象处于已定义但受限制的状态。严格来说,建设成功了,但可能不是呼叫者希望的程度。他可以选择以后完成施工。
  3. 1。施工失败

    我将在下面的代码中使用您的ConstructA,以便指出有关构造失败的信号:

    A a0;
    try {
        A::ConstructA a1(a0);
    } catch(...) {
        // fail to construct a1
    }
    

    构造函数抛出异常以在其构造失败时发出信号。 这个想法是,如果一个对象的构造失败,那么就不会构造该对象。换句话说,该对象不存在。如果你必须在构造函数初始化列表中初始化a1,那么也有一种方法:

    struct B {
        B() try : a1(a0) { 
            // other constructor code...
        } catch(...) {
            // fail to construct either a0 or a1, or constructor 
            // code threw
        }
        A a0;
        A::ConstructA a1;
    };
    
    try {
        B b;
    } catch(...) {
        // fail to construct B
    }
    

    首先,执行构造函数的catch块中的代码,然后将异常自动传播到创建B对象的代码,并考虑其catch块。

    您的类ConstructA的构造函数可能如下所示,例如:

    struct ConstructA {
        ConstructA(A &a):a(a) {
            if(!condition_met) {
                throw std::runtime_error("condition_met false");
            }
        }
        A &a;
    };
    

    2。对象处于受限状态

    具有文件流对象但未连接到文件的情况就是如此。如果在构造函数中发现提到的文件不存在,您仍然可以完全构造流,但将其设置为 not-opened 状态。某些操作可能会被禁止,您可以使用isOpenisValid函数来查询对象的状态。 这也适用于其他情况。我使用的一些框架有一个Color类。默认构造一个颜色类使其处于无效状态,因此它不会与任何有效颜色相等:

    Color c;
    assert(c.isValid() == false);
    

    相同的技术用于空指针。当您为其分配 NULL 时,它被设置为已定义但受限制的状态:

    int *a = NULL;
    assert(a == NULL);
    

    例如,您不能取消引用空指针。

答案 3 :(得分:0)

你是ConstructA只是试图抓住已经构建的A的引用,尝试将其改为:

  class ConstructA {
       A a; // Don't make this a reference
       public:
       ConstructA (A& ta) : a(ta) {}
       ...

  };

答案 4 :(得分:-2)

mkal,我总是建议人们不要在C ++中使用异常。它会导致更多问题,试图解决。

要回答你的问题,为了避免C ++中的异常,你可能会减少你的工作量 想在你的构造函数中做,并创建一个init()方法,如果出现问题则返回错误代码。

基本上,无论你在C ++构造函数中做什么,它都必须成功。

希望有所帮助。