避免析构函数调用特定异常

时间:2015-12-09 15:00:34

标签: c++

我在这里简化了我的问题,因为我有一个非常大的代码库而且我无法创建一个mcve。

我有一个可能会或可能不会成功构建的对象。如果没有,则在其构造函数

中抛出类型ObjectUnsupported的异常
class Object {
public:
  Object() {

    read_data1();
    ..
    if(unsupported_kind == true)
      throw ObjectUnsupported();
    ..
    read_data2();
  }
  std::vector<char> data1;
  std::vector<char> data2;
};

data1 始终读取,而data2仅适用于受支持的对象。

现在,我尝试使用智能指针

在其他地方构建对象
std::unique_ptr<Object> obj;
try {
  obj = std::make_unique<Object>();
} catch(ObjectUnsupported& ex) {
  object_is_unsupported = true;
}

if(object_is_unsupported) {
  if(checkIfDataIsNeeded(obj->data1) == false)
    return; // We didn't need it anyway
  else
    throw RuntimeError(); // Data was needed! Abort!
}

data1总是在data2不是,但这里的重点是:我可能需要data2或者我可能需要该对象

上面的代码不起作用,因为调用obj智能指针的析构函数因此导致后续代码错误。

我如何实现目标?

1 个答案:

答案 0 :(得分:2)

从构造函数中抛出异常不会给你留下半构造的对象。按照设计,该对象不存在。构建到例外点的所有成员都将被销毁。

这里的解决方案是让你的对象支持一个标志,指示它有多少数据。

例如:

class Object {
public:
    Object() {

        read_data1();
        ..
        if(!unsupported_kind)
        {
            read_data2();
            _has_supported_data = true;
        }
    }

    bool has_supported_data() const {
        return _has_supported_data;
    }

    std::vector<char> data1;
    std::vector<char> data2;

private:
    bool _has_supported_data = false;
};