尝试捕获 class 变量初始化的作用域

Try catch scoping of class variable initialisation

我在尝试找到一个解决方案时遇到困难,该解决方案允许我将对象的范围保持在 main 方法的本地,同时捕获潜在的初始化异常。

下面的伪代码试图最好地说明我的问题。

int main () {
    // Initialisation
    SomeObject * object;

    try {
         SomeObject obj; // Initialisation can cause an exception
         object = &obj;
    }
    catch (SomeException &ex) {
         // Handle exception
    }

    // object out of scope undefined behaviour

    // Application Logic
    return 0;
}

我知道一旦 try 块结束,对象将被删除,因此使用指针会导致未定义的行为。

我怎样才能做这样的事情并将对象传递给函数范围,这样对象就不会被删除?

我可以在我的项目中使用 c++14 解决方案。

How can I do something like this and pass the object to the function scope so the object is not deleted?

您可以改用智能指针:

int main () {
    // Initialisation
    std::unique_ptr<SomeObject> object;

    try {
         object = std::make_unique<SomeObject>(); // Initialisation can cause an exception
    }
    catch (SomeException &ex) {
         // Handle exception
    }

    if(object) {
        // Application Logic
    }
    return 0;
}

显而易见的方法是 "function try block"

int main() try
{
     SomeObject object;

     // Application logic - able to use object

     return 0;
}
catch (SomeException &ex)
{
     // Handle exception
}

这允许异常处理程序在程序终止之前进行清理。

如果您想要 main() 内的异常处理程序,那么一个选项是

 int main()
 {
      try
      {
           SomeObject object;

            // Application logic able to use object
      }     
      catch (SomeException &ex)
      {
           // Handle exception
      }
}

通过适当的控制结构(例如循环中的整个 try/catch),catch 块可以从错误中恢复并重新开始。

如果你真的希望对象的定义和初始化是分开的,你可以这样做(C++11 及更高版本);

#include <memory>
int main ()
{
    std::unique_ptr<SomeObject> object;

     try
     {
          object = std::make_unique<SomeObject>();
     }
     catch (SomeException &ex)
     {
         // Handle exception
     }

     // code here cannot assume construction of object succeeded

     if (object)
     {
         // Application Logic can assume object is properly constructed
     }
    return 0;
}

在 C++11 之前,以上可以使用 std::auto_ptr(在 C++11 中已弃用,取而代之的是 unique_ptr

合适的选择取决于您是否希望 "Application logic" 能够 假设 object 已被正确构造(即应用程序逻辑永远不会执行直到对象构造成功)或者它是否必须测试失败的可能性。