【问题标题】:Try catch scoping of class variable initialisation尝试捕获类变量初始化的范围
【发布时间】:2017-05-28 00:22:15
【问题描述】:

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

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

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

【问题讨论】:

  • to keep the scope of an object local to a main method - 为什么在这种情况下而不是在你想使用它的范围内声明它?如果您在子函数中将对象声明为局部变量 - 在您从该子函数退出到 main 后,任何方式都将是垃圾。所以如果你需要在main 范围内有对象 - 在这里声明它

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


【解决方案1】:

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

您可以改用智能指针:

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

【讨论】:

  • 谢谢,我相信这是我需要的。
【解决方案2】:

显而易见的方法是“函数尝试块”

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

【讨论】:

    猜你喜欢
    • 2017-08-20
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多