尝试catch语法构造函数 [英] Try catch syntax constructor

查看:87
本文介绍了尝试catch语法构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

http://ideone.com/UtVzxw

  struct base 
{
base(){throw std :: exception(); }
};

结构派生:公共基础
{
派生()try:base(){}

catch(std :: exception&e)
{
std :: cout<< 已处理的例外<< std :: endl;
}
};

int main()
{
得出a; //我的应用崩溃了。
返回0;
}

我的应用程序不应该编写异常处理并继续运行吗? p>

我发现的唯一解决方案是在try / catch块中包含 a 的构造。但是,如果我这样做了,那么首先在构造函数中进行try / catch的意义是什么?我猜想它的用途是清除可能已分配的成员变量?因为未调用析构函数



以下方法有效,但是处理了两次异常。

  struct base 
{
base(){throw std :: exception(); }
};

结构派生:公共基础
{
派生()try:base(){}

catch(std :: exception& e)
{
std :: cout<< 例外1<< std :: endl;
}
};

int main()
{
//可以正常工作。
try {
得出a;
}
catch(std :: exception& e)
{
std :: cout<< 例外2<< std :: endl;
}
返回0;
}

我只是想问问自己为什么我不应该简单地躲避尝试/捕获构造函数的语法,并写成这样:

  struct base 
{
base(){抛出std :: exception(); }
};

结构派生:公共基础
{
派生():base(){}
};

int main()
{
//可以正常工作。
try {
得出a;
}
catch(std :: exception& e)
{
std :: cout<< 已处理的例外<< std :: endl;
}
返回0;
}


解决方案

function-try构造函数中的-block 不会阻止引发异常。这是C ++标准草案N4140的摘录,[句柄除外]:


14 如果在构造函数的 function-try-block 的处理程序中出现return语句,则程序格式错误。



15 如果控制到达构造函数或析构函数的 function-try-block 的处理程序的末尾,则当前处理的异常将被抛出。否则,...


其原因是,如果基类或任何成员构造函数引发异常,则构造整个对象失败,并且无法修复,因此必须引发异常。



有一个 GOTW ,底线是


构造函数function-try-block处理程序只有一个目的-转换异常。 (并且可能做日志记录或其他一些副作用。)它们对于任何其他目的都没有用。


所以,是的,最后一个代码示例非常好。


http://ideone.com/UtVzxw

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() try : base()  { }

    catch (std::exception& e)
    {
        std::cout << "exception handled" << std::endl;
    }
};

int main()
{
    derived a; // My app crashes.
    return 0;
}

Shoun't my app write "exception handled" and continue running?

The only solution I've found is to surround the construction of "a" in a try/catch block. But If I do that, what's the point of having the try / catch in the constructor at the first place? I'm guessing maybe it's use is to clean up member variables that may have been allocated? since the destructor is not called?

The following works, but handles the exception 2 times.

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() try : base() { }

    catch(std::exception& e)
    {
      std::cout << "exception 1" << std::endl;
    }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception 2" << std::endl;
    }
    return 0;
}

I'm just trying to ask myself why I shouldn't simply dodge the try / catch syntax for the constructor and write this:

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() : base() { }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception handled" << std::endl;
    }
    return 0;
}

解决方案

function-try-block in the constructor doesn't prevent the exception from being thrown. Here's an excerpt from C++ standard draft N4140, [except.handle]:

14 If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.

15 The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. Otherwise, ...

The reason for this is that if base class or any member constructor throws an exception, then the construction of the whole object fails, and there's no way to fix it, so the exception has to be thrown.

There's a GOTW on this, and the bottomline is

Constructor function-try-block handlers have only one purpose -- to translate an exception. (And maybe to do logging or some other side effects.) They are not useful for any other purpose.

So, yes, your last code sample is perfectly fine.

这篇关于尝试catch语法构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆