[英]C++ bad_alloc thrown in a constructor
當在構造器中拋出bad_alloc
異常(在該構造器中創建多個對象)時,必須執行清理內存的操作。 例如
class Object
{
private:
A * a;
B * b;
public:
Object()
{
a= new A();
b= new B(); //So if a bad_alloc is called here, how is a deleted???
}
}
我的直覺是將對new的每個調用放在單獨的try catch bloc中,並刪除以前為其調用new
所有對象,但這太冗長了(第一個try bloc不調用析構函數,第二個類調用第一個,第三個調用前兩個等)。 我的問題是:最常見的處理方式是什么?
另外,可以說類對象包含一個不是用new創建的對象(因為它在堆棧上),它的析構函數會自動調用嗎?
您要使用智能指針:
class Object {
std::unique_ptr<A> a;
std::unique_ptr<B> b;
public:
Object() : a(make_unique<A>()), b(make_unique<B>()) {}
}
首先,我修復了您的代碼,因為這是一個C ++問題,因此必須將其編寫為C ++。 構造函數可能會因bad_alloc之外的異常而失敗。
您有以下選擇:
不存儲指針,但存儲對象。 這些是自動構造的(或通過初始化列表),如果創建,則將自動清除。 這可能會更好,但是意味着它們需要完全定義,即包括其標頭,並且您可能試圖隱藏實現細節/分離。
存儲某種智能指針,例如unique_ptr
,它實際上是一個對象,因此像對象一樣被清理,如果有則刪除基礎指針。
將常規指針存儲在您的類中,但在構造函數期間使用unique_ptr
(如果無法使用unique_ptr
則使用auto_ptr
),最后,當您知道一切都已正確構建時,可以將智能指針釋放到成員變量中。
后一種解決方案如下所示:
// header file
//
class A; // implementation hidden on purpose
class B; // ditto
class Object
{
private:
A * a;
B * b;
public:
Object();
~Object();
private:
// if not using C++11 do not put in =delete but still declare these
Object( const Object & ) = delete;
Object& operator=( const Object & ) = delete;
};
// cpp file
#include "object.h"
#include "a.h"
#include "b.h"
Object::Object()
: a( nullptr ), // use NULL or 0 if nullptr not available
b( nullptr )
{
std::unique_ptr< A > pa( new A ); // might throw
std::unique_ptr< B > pb( new B ); // might throw (1)
a = pa.release(); // cannot throw
b = pb.release();
}
Object::~Object()
{
delete b;
delete a;
}
(1)如果它拋出了局部的pa
,則將調用其析構函數,這將刪除使用new創建的指針。
注意:如果您沒有unique_ptr
可用,則auto_ptr
也可以在此處使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.