c ++中的功能范例异常处理 - 是不好的风格吗? [英] Function-wide exception handling in c++ - is it a bad style?

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

问题描述

  bool function()这个函数有一个try-catch的东西, 
try
{
// do something
}
catch(exception_type& t)
{
// do something
}

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

具体示例我使用这种方法:



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



之前的功能:

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

}
}

之后:

  bool readEntity(...)
try
{
while(...)
{
if(...)
{
// lot's of code ...
}
}
}
catch(XMLBaseException& ex )
{
//创建我们的异常并抛出
}

我的想法是这样的:我清楚地表示我的意图是将所有从一个类型导出的异常转换为自定义类型。我们保持屏幕没有水平滚动条(导致横向滚动条不好)。



嗯,实际上,我在这个方法中被批评为不清楚的代码审查。



所以我想听听你的想法。



更新:只是要明确:重构功能不是一个选择。实际上这是一个很好的写作。

解决方案

真正的功能级try块的唯一原因是构造函数,否则就是有些模糊的功能,不会买你那么多。这样做很简单:

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

如果您遇到水平滚动问题,那么要做的就是拆分代码。尝试/捕获是复杂的,这应该在嵌套级别中表示,而不是隐藏。



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

  SomeClass :: SomeClass(参数p1,参数p2):Member1(p1),Member2(p2) 
尝试
{
}
catch(异常& ex)
{
//处理和重新抛出
}

当然,如果您在建设中有异常情况,除了日志和重新抛出之外,还可能无法进行恢复(在构造函数的情况下它将被重新抛出)。您的对象尚未完全构建,您无法真正做到这一点。您唯一可信任的有效参数是参数(尽管如果初始化失败,这可能是因为参数不好)。



请参阅 GOTW for对此的讨论。


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天全站免登陆