在哪里可以找到有关C ++ / STL方法异常保证的信息? [英] Where can I find information about C++/STL method Exception guarantees?

查看:124
本文介绍了在哪里可以找到有关C ++ / STL方法异常保证的信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



基本上,假设你有:

/ p>

  class X {
string m_str;
X():m_str(foo)//如果这抛出了怎么办?
{
ifstream b(a.in)//如果这抛出了怎么办?
}



在浏览所有文章后,我还是不知道



说我有一个代码:

 

code> {
...
X myInstanceOfClassX;
...
}

$ c> catch(exception&)?如果我这样做, string ifstream 保证强大的保证,没有资源泄露,如果我的类引发 myexception ,那是从异常派生的, catch(exception&)似乎让它通过。所以让我留下 catch(...)哪个IIRC捕获访问违例?有没有另一种方法?



然后有一条信息,在任何异常抛出的对象构造函数的子构造函数不应该被捕获,并且构造函数应该抛出的成员对象throw。



如果上面的代码不是从构造函数调用,而是从常规的函数 void foo ,我应该捕获哪些异常?内容提要?在哪里可以找到什么STL对象可以抛出的定义?



哪里是权威来源,我可以清除我对这个主题的所有疑问和问题?



到目前为止,处理例外似乎是在一大堆gooo中跳舞。错误代码似乎一个更简单,更安全...

解决方案

如果任何一个抛出

  class X {
string m_str;
X():m_str(foo)//如果这抛出了怎么办?
{
ifstream b(a.in)//如果这抛出了怎么办?
}

然后您创建的对象将不存在。

如果在对象的构造函数中抛出异常,则所有完全创建的成员都将被销毁(使用它们的析构函数),并且该对象的内存将返回到系统。因此,在抛出点处未完全构造的任何成员都不会被销毁(因为它们尚未创建)。




  • 如果m_str )抛出了初始化器列表,那么对象将永远不存在。

  • 如果ifstream抛出在body中,则m_str被销毁,对象将永远不存在。




我应该在catch(exception&)中包装代码吗?如果我这样做,字符串和ifstream是否保证有力的保证,没有资源泄露,没有任何东西被打开。


即使捕获异常(对象外),也没有任何对象可以工作,因为它从未存在(对象只在构造函数完成后才开始其生命周期)。



在上面你保证没有泄漏或开放的资源。


此外,如果我的类抛出myexception, ,catch(exception&)似乎让它通过。所以我留下了catch(...)哪个IIRC捕获访问违例?是否有另一种方式?


如果你的异常派生自std :: exception然后 catch(std ::异常&)将工作。如果它不工作,那么你在做错误的事情(但我们需要更多的细节(如代码和代码捕获,英语描述不够))。


然后有一个信息,在任何异常抛出的对象构造函数的子构造函数不应该被捕获,并且构造函数应该抛出的情况下任何成员对象throw。


可能是最好的选择,一般来说不是不好的建议。


如果上面的代码不是从构造函数调用,而是从常规的函数void foo(),我应该捕获哪些异常?内容提要?在哪里可以找到什么STL对象可以抛出的定义?是否具体实现?


您应该只捕获异常,如果你可以做一些事情。通常这是没有什么不要;他们让应用程序正常退出(通过异常展开堆栈)。


权威来源,我可以清除我对这个主题的所有疑问和问题。


你的问题是如此多样, br>
我可以推荐Herb Sutter的异常C ++。 p>


到目前为止,处理异常似乎就像在一堆gooo中跳舞一样。错误代码似乎一个更简单,更安全...


你错了。异常更容易。你只是似乎过度思考它,并感到困惑。这不是说错误代码没有自己的位置。



如果出现错误,你不能在本地修复它然后抛出异常。标准中的所有类都设计有例外,并且行为正确。



经验法则:(对于你的对象)





  • 如果您的对象包含资源,请确保遵守规则3。



  • 注意:你可以有多个东西像std :: string或std :: ifstream,因为它们是控制资源的(它们每个控制一个资源,所以你的类不控制资源)。资源(在此上下文中)是您必须手动创建/销毁的资源。



就是这样,其余的自动工作。


I was writing code with exception handling the other day, and I had a few questions about exceptions, their guarantees and throwables.

Basically, say you have:

class X {
string m_str;
X() : m_str("foo")//what if this throws?
{
    ifstream b("a.in")//what if this throws?
}

And after running through all the articles I could find, I still have no idea what is the clean way to handle this.

Say I have a code like:

{
    ...
    X myInstanceOfClassX;
    ...
}

Should I wrap the code in catch(exception &)? And if I do that, does string and ifstream guarantee a strong guarantee, that no resources are leaked and nothing has been left half opened?

Also, if my class throws myexception, that is derived from exception, catch(exception &) seems to let it through. So that leaves me with catch(...) which IIRC catches access violation?.? Is there another way?

Then there was a piece of information somewhere that any exception thrown in subconstructors of object constructor shouldn't be caught, and constructor should throw in case any of the member objects throw.

And what if the code above would have been called not from constructor, but from regular a function void foo(), which exceptions should I catch? outofmemory_something, filenotfound_something? Where can I find the definitions of what STL objects can throw? Are they implementation specific?

Where is the authoritative source where I could clear all my doubts and questions on this topic?

So far, it seems that handling exceptions is like dancing in a big pile of gooo. Error codes seem A LOT simpler and safer...

解决方案

If either of these throw

class X {
string m_str;
X() : m_str("foo")//what if this throws?
{
    ifstream b("a.in")//what if this throws?
}

Then the object you were creating will not exist.
If an exception is thrown in the constructor of an object, then all fully created members are destructed (using the their destructor) and memory for the object is returned to the system. Thus any members that are not fully constructed at the throw point will not be destroyed (as they have not been created).

  • If m_str() throws in the initializer list then the object will never exist.
  • If ifstream throws in the body then m_str is destroyed and the object will never exist.

Should I wrap the code in catch(exception &)? And if I do that, does string and ifstream guarantee a strong guarantee, that no resources are leaked and nothing has been left half opened?

Even if you catch an exception (outside the object) there is no object to work on as it never existed (the object only starts its lifespan after the constructor completes).

In the above you are guaranteed there are no leaks or open resources.

Also, if my class throws myexception, that is derived from exception, catch(exception &) seems to let it through. So that leaves me with catch(...) which IIRC catches access violation?.? Is there another way?

If your exception is derived from std::exception then catch(std::exception&) will work. If it is not working then you are doing something wrong (but we need more detail (like the code that throws and the code that catches, an English description is not adequate)).

Then there was a piece of information somewhere that any exception thrown in subconstructors of object constructor shouldn't be caught, and constructor should throw in case any of the member objects throw.

Probably the best option and as a general rule not bad advice.

And what if the code above would have been called not from constructor, but from regular a function void foo(), which exceptions should I catch? outofmemory_something, filenotfound_something? Where can I find the definitions of what STL objects can throw? Are they implementation specific?

You should only catch exceptions if you can do something about it. Usually this is nothing so don;t catch them let the application quit normally (via the exception unwinding the stack).

Where is the authoritative source where I could clear all my doubts and questions on this topic?

You're question are so varied that that is hard.
I could recommend "Exceptional C++" by Herb Sutter.

So far, it seems that handling exceptions is like dancing in a big pile of gooo. Error codes seem A LOT simpler and safer...

You are wrong there. Exceptions are much easier. You just seem to be over-thinking it and getting confused. That is not to say that error codes do not have their place.

If something goes wrong and you can not fix it locally then throw an exception. All the classes in the standard are designed with exception in mind and will behave correctly. So that just leaves your classes.

Rules of thumb: (for your objects)

  • Make sure your classes clean themselves up in the destructor
  • If your object contains resources make sure the "rule of 3 is obeyed"
  • Never have more than one resource per object.
    Note: You can have multiple things like std::string or std::ifstream as they are the ones controlling the resource (they each control one resource so your class is not controlling the resource). A resource (in this context) is something that you must manually create/destroy.

That's it, the rest auto-magically works.

这篇关于在哪里可以找到有关C ++ / STL方法异常保证的信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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