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

时间:2017-05-28 00:22:16

标签: c++ windows exception undefined-behavior scoping

我在尝试找到一个解决方案时遇到困难,这个解决方案允许我在捕获潜在的初始化异常时将对象的范围保持在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解决方案。

2 个答案:

答案 0 :(得分:2)

  

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

您可以改用智能指针:

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

答案 1 :(得分:1)

显而易见的方法是“功能尝试块”

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已正确构造(即,在对象构建成功之前,应用程序逻辑永远不会执行)或者如果它必须测试失败的可能性。