c ++中的函数范围的异常处理 - 这是一个坏的风格吗? [英] Function-wide exception handling in c++ - is it a bad style?

查看:115
本文介绍了c ++中的函数范围的异常处理 - 这是一个坏的风格吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个try-catch的功能,我认为有时可能是非常有用的:

  bool function 
try
{
//做某事
}
catch(exception_type& t)
{
//做某事
}

所以问题的第一部分是:这种风格在一般情况下被认为是坏的吗? p>

我使用这种方法的具体例子:



我们在c中有了很多代码, c ++。而且我们有自定义的异常类型(不是std :: exception派生)。我需要集成XML库,并将所有异常转换为我们的类型。因此,基本上,最后一步是从XML库捕获所有异常并转换它们。



之前的功能:

  bool readEntity b $ b {
while(...)
{
if(...)
{
//代码...
}
}
}

之后:

  bool readEntity(...)
try
{
while(...)
{
if(...)
{
//很多代码...
}
}
}
catch(XMLBaseException& ex )
{
//创建我们的异常并抛出
}

我的想法是这样的:我清楚地说明我的意图将所有从一种类型派生的异常转换为自定义类型,我们保持我们的屏幕没有水平滚动条(因为水平滚动条是坏的)。



好吧,我实际上对这种方法非常批评,因为在代码审查期间不清楚。



所以我想听听你的想法。



UPDATE :just要清楚:重构函数不是一个选项。

解决方案

真正的功能级try块的唯一原因是构造函数,否则它是一个有些模糊的功能,不会买你那么多。它很容易做到这一点:

  bool readEntity(...)
{
try
{
while(...)
{
if(...)
{
//代码...
}
}
}
catch(XMLBaseException& ex)
{
//创建我们的异常并抛出
}
}

如果你有水平滚动的麻烦,那么你要做的就是拆分你的代码。 try / catch是复杂的,这应该在嵌套级别表示,而不是隐藏。



在构造函数中,这是一个不同的问题:没有其他方法捕获异常在初始化器列表中:

  SomeClass :: SomeClass(参数p1,参数p2):Member1(p1),Member2 
try
{
}
catch(Exception& ex)
{
// handle and rethrow
}

当然,如果你在构建期间有一个异常,你可能无法恢复除日志和rethrow (它将在构造函数的情况下重新抛出)。你的对象没有完全构建,没有什么你真的可以做到。你唯一可以信任的是有效的参数(虽然如果初始化失败,这可能是由于错误的参数)。



有关此问题的讨论,请参阅此 GOTW


There is a try-catch thing about functions, which I think sometimes may be quite useful:

bool function() 
try
{
    //do something
}
catch(exception_type & t)
{
   //do something
}

So the first part of the question: is this style considered bad in general case?

And the concrete example I used this approach in:

We had project with quite a lot of code in c and c++. And there we had custom exception types (not std::exception derived). I needed to integrate XML library and cast all exception to our types. So, basically, the last step was to catch all exceptions from XML library and convert them.

Function before:

bool readEntity(...)
{
   while(...)
   { 
      if(...)
      {
         //lot's of code...
      }
   }
}

after:

bool readEntity(...)
try
{
   while(...)
   { 
      if(...)
      {
         //lot's of code...
      }
   }
}
catch(XMLBaseException & ex)
{
    //create our exception and throw
}

My thoughts went something like this: I clearly state my intentions to convert all exception derived from one type into custom type AND we keep our screen without horizontal scroll bar (cause horizontal scroll bars are bad).

Well, I actually was quite criticized for this approach as for non-clear one during code review.

So I'd like to hear you thoughts.

UPDATE: just to be clear: refactoring the function wasn't an option. And actually it was good written one.

解决方案

Really the only reason to function-level try blocks is for constructors, otherwise it's a somewhat obscure feature that doesn't buy you that much. It's just as easy to do it this way:

bool readEntity(...)
{
   try
   {
      while(...)
      { 
         if(...)
         {
            //lot's of code...
         }
      }
   }
   catch(XMLBaseException & ex)
   {
       //create our exception and throw
   }
}

If you are having troubles with horizontal scrolling then the thing to do is to split up your code. try/catches are complexity and this should be represented in the nesting level, not hidden.

In constructors, this is a different issue: there is no other way to catch exceptions in an initializer list:

SomeClass::SomeClass(parameter p1, parameter p2) : Member1(p1), Member2(p2)
try
{ 
}
catch(Exception &ex)
{
    // handle and rethrow
}

Of course, if you have an exception mid-construction, there's not likely much you can do to recover except log and and rethrow (it's going to get rethrown anyway in the constructor case). Your object isn't completely constructed yet and there's nothing you can really do with it. The only thing that you can trust to be valid are the parameters (although if the initialization failed, that will likely be due to bad parameters).

See this GOTW for a discussion on this.

这篇关于c ++中的函数范围的异常处理 - 这是一个坏的风格吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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