在C ++ construtor中管理bad_alloc异常 [英] Manage bad_alloc exception in C++ construtor

查看:189
本文介绍了在C ++ construtor中管理bad_alloc异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Java经验,最近在做一些C ++编码。我的问题是,如果我有类A,我必须实例化类B和类C作为A的两个成员变量。

I have Java experience and recently am doing some C++ coding. My question is that if I have class A, in which I have to instantiate class B and class C as two of the member variables of A.

如果在构造函数A,我应该假设类B和C的分配永远不会失败,并处理在A的析构函数中的不良分配异常?

If in the constructor of A, should I assume that allocations of class B and C never fail, and handle the bad allocation exception in the destructor of A?

如果我不这样做,意味着我添加一些try catch块来捕获B类和C类的bad_alloc,那么如果发生分配异常,我做清理在A的构造函数?

If I don't make that assumption, meaning that I add some try catch block to catch bad_alloc of class B and class C, then if the allocation exception occurs, should I do clean up in the constructor of A?

推荐的做法是什么?如果new产生一个坏的分配,指针有什么价值?

What are the recommended practices? If "new" generates a bad allocation, what value does the pointer carry?

推荐答案

如果在构造A期间抛出异常,您的析构函数不会被调用。

If an exception is thrown during the construction of A, your destructor will not be called.

显然,解决方案取决于您的操作,但理想情况下您不会有任何清理。您应该使用 RAII ,您的班级成员应自行清理。

Obviously the solution depends on what you're doing, but ideally you won't have to do any cleaning up. You should utilize RAII, and your class members should clean-up themselves.

也就是说,不要使用任何指针raw;包装它们,让包装器照顾它。惊喜! C ++程序员讨厌内存管理就像你。

That is, don't use any pointers raw; wrap them up and let the wrapper take care of it. Surprise! C++ programmers hate memory management just like you. We like to wrap it up and forget about it.

如果你真的需要,我认为这是很常见的:

If you truly need to, though, I think this is common:

struct foo
{
    int* i;
    some_member_that_could_throw crap;

    foo() // do *not* new i! if the second member throws, memory is leaked.
    {     // rather:

        // okay we made it, the other member must have initialized
        i = new int;
    }
};






关于指针,它的值保持不变。当 new 抛出一个异常(无论什么原因),堆栈被解开。


Concerning your pointer, it's value remains unchanged. When new throws an exception (for whatever reason), the stack is unwound. The rest of the expression is abandoned.

下面是异常和对象创建的工作原理。这是一个递归的过程,因为每个成员或基类将依次遵循此列表。基本类型没有构造函数;这是递归的基本情况。

Here's how exceptions and object creation will work. It's a recursive process, because each member or base class will in turn follow this list. Fundamental types have no constructors; this is the base case for the recursion.


  1. 首先,构造每个基类。

  2. 逐个初始化类的成员。

  3. 运行构造函数体

  4. 完成一个完全构造的对象。

  1. First, construct each of our base classes. (Which in turn run this list.)
  2. Initialize members of the class, one by one.
  3. Run the constructor body.
  4. finish with a fully constructed object.

显然,如果项目1失败,为我们做,因为我们的成员没有被初始化。我们很好。

Obviously, if item 1 fails there isn't any cleaning up for us to do, as none of our members have been initialized. We're good there.

两个不同。如果在任何时候其中一个无法构造,到目前为止的已初始化的成员将被销毁,那么构造函数将停止进度,异常继续它的快乐方式。这就是为什么当你让你的成员自己清理后你没有什么可担心的。未初始化的没有任何事情,初始化将使它们的析构函数运行,在那里清理发生。

Two is different. If at any point one of those fails to construct , the initialized members so far will be destructed, then the constructor will stop progress and the exception goes on it's merry way. This is why when you let your members clean up after themselves you have nothing to worry about. The uninitialized have nothing to do, and the initialized are going to have their destructors run, where cleanup occurs.

三个更多。现在你的对象被完全初始化,你保证他们都将运行它们的析构函数。再次,包装东西,你没有什么可担心。 如果你有一个原始指针,这是try / catch块的时间:

Three even more so. now that your objects are fully initialized, you're guaranteed they will all have their destructors run. Again, wrap things up and you have nothing to worry about. However if you have a raw pointer lying around, this is the time for a try/catch block:

try
{
    // some code
}
catch (..) // catch whatever
{
    delete myrawPointer; // stop the leak!
    throw; // and let the exception continue
}

编写异常安全代码更麻烦没有RAII。

It's much messier to write exception-safe code without RAII.

这篇关于在C ++ construtor中管理bad_alloc异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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