尝试捕获类变量初始化的范围



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

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

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 解决方案。

如何执行此操作并将对象传递给函数范围,以便不删除对象?

您可以改用智能指针:

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;
}

显而易见的方法是"函数尝试块">

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

合适的选择取决于您是希望"应用程序逻辑"能够假设object已正确构造(即在对象构造成功之前永远不会执行应用程序逻辑(,还是必须测试失败的可能性。

最新更新