【问题标题】:Object declaration in try and catch not defined in scopetry 和 catch 中的对象声明未在范围内定义
【发布时间】:2014-02-24 10:33:56
【问题描述】:

我想在 try / catch 语句中声明一个对象,如下所示:

try {
  Object object(value);
} catch (exception) {
  return 1;
}
object.usingExemple();

G++ 告诉我对象未在范围内定义。

我明白,如果 try 接收到异常对象,则不会创建并且无法使用。 但是如果发生这种情况,g++ 不应该知道我会离开这个函数吗?

如何在不使用 new 的情况下声明一个在构造函数中引发异常的对象?

提前致谢:)

【问题讨论】:

    标签: c++ exception constructor try-catch


    【解决方案1】:

    简单:如果您的代码使用object 依赖于它的创建而不引发异常(它确实,因为如果发生异常,对象不可用),那么它被与对象的创建相同的条件覆盖。只需将所有使用 object 的代码移动到 try 块中:

    try {
      Object object(value);
      object.usingExemple();
    } catch (exception) {
      return 1;
    }
    

    关于错误本身发生的原因:try 中的块语句引入了嵌套范围,就像任何其他大括号对一样。该范围内的所有声明都是该范围内的 - 因此标识符 object 不再存在于该范围之外。


    请注意,我上面的代码并不完全等同于您的原始代码,因为usingExample() 抛出的异常现在也将被捕获(感谢@immibis 指出这一点)。如果这对您来说不可接受,您将不得不求助于动态分配:

    std::unique_ptr<Object> objectPtr;
    try {
      objectPtr.reset(new Object(value));
    } catch (exception)
      return 1;
    }
    Object &object = *objectPtr;
    object.usingExample();
    

    理论上,您也可以使用布置new,但我不建议将其作为简单的“对于手头的问题来说太奇怪的解决方案:”

    alignas(Object) unsigned char objectStorage[sizeof(Object)];
    Object *objectPtr;
    try {
      objectPtr = new (&objectStorage) Object(value);
    } catch (exception) {
      return 1;
    }
    try {
      Object &object = *objectPtr;
      object.usingExample();
    } catch (...) {
      objectPtr->~Object();
      throw;
    }
    

    【讨论】:

    • 如果object.usingExample(); 抛出异常,这段代码不会做同样的事情。
    猜你喜欢
    • 2016-03-04
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多