try和catch中的对象声明未在作用域中定义

nsv*_*vir 5 c++ constructor exception try-catch

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

try {
  Object object(value);
} catch (exception) {
  return 1;
}
object.usingExemple();
Run Code Online (Sandbox Code Playgroud)

G ++告诉我对象没有在范围中定义.

我明白,如果尝试收到异常对象,则不会创建并且无法使用.但是,如果它发生的话,g ++应该知道我离开了这个功能吗?

如何在不使用new的情况下声明在构造函数中抛出异常的对象?

提前致谢 :)

Rei*_*ica 5

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

try {
  Object object(value);
  object.usingExemple();
} catch (exception) {
  return 1;
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

从理论上讲,您也可以使用 position 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`object.usingExample();` 抛出异常,则这段代码不会做同样的事情。 (2认同)