0

我正在尝试使我的 C++ 代码异常安全,但遇到了一个问题,无论是询问朋友还是搜索网络都无济于事。

据我了解,当使用构造函数创建对象时可能会引发异常,创建代码需要用try块括起来,异常处理在catch(){}.

如果创建是基于堆的(例如new,使用默认分配器编辑),我可以将异常处理代码放置在创建附近,如下所示:

void f() {
  // work unrelated to Hoge object here

  try {
    Hoge *pHoge = new Hoge(); // could throw an exception
  } catch(HogeException& ex) {
    // handle exception
  }

  // rest of work here
}

但是,如果创建是基于堆栈的,由于块的范围,我找不到这样做的方法并求助于下面的代码try

void g() {
  // work unrelated to Hoge object here

  try {
    Hoge hoge; // could throw an exception

    // rest of work here
  } catch(HogeException& ex) {
    // handle exception
  }
}

如果// rest of work上面的代码很大,对象创建和异常处理之间的位置距离可能会很长,从而降低代码的可读性......

我更喜欢异常处理代码靠近对象创建(也许这是结构的概念之一trycatch。有什么解决办法吗?

4

2 回答 2

5

将 委托// rest of work给辅助函数,并将 a 传递Hoge&给该函数:

void RestOfWork(Hoge& hoge)
{
  // rest of work here
}

void g() {
  // work unrelated to Hoge object here

  try {
    Hoge hoge;
    RestOfWork(hoge);
    // rest of work here
  } catch(HogeException& ex) {
    // handle exception
  }
}

顺便说一句,Hoge hoge();不做你认为它做的事。您可能认为您正在声明一个名为hogetype的对象Hoge,并通过调用默认构造函数对其进行初始化。你实际上在做的是声明一个名为的函数hoge,它不带参数并返回一个Hoge值。我已经在上面的代码中解决了这个问题。

编辑确实,正如@LightnessRacesInOrbit 所建议的那样,Hoge对象的构造也可以在延迟函数中进行,例如:

  void RestOfWork()
  {
       Hoge hoge;
      // rest of work here
  }

  void g() {
    // work unrelated to Hoge object here

    try {
      RestOfWork();
    } catch(HogeException& ex) {
      // handle exception
    }
  }
于 2012-11-23T13:49:27.043 回答
0

一种合理的方法是使用可为空的单项容器,例如boost::optional

void g() {
  // work unrelated to Hoge object here

  boost::optional<Hoge> opt_hoge;
  try {
    opt_hoge = boost::in_place<Hoge>();
  } catch(HogeException& ex) {
    // handle exception
  }
  Hoge &hoge = *opt_hoge;

  // rest of work here
}

如果您不能使用 Boost,std::unique_ptr则会以堆分配为代价:

void g() {
  // work unrelated to Hoge object here

  std::unique_ptr<Hoge> opt_hoge;
  try {
    opt_hoge = std::unique_ptr<Hoge>(new Hoge);
  } catch(HogeException& ex) {
    // handle exception
  }
  Hoge &hoge = *opt_hoge;

  // rest of work here
}
于 2012-11-23T14:29:18.053 回答