これはコンパイルされますが、他のコードでは見たことがありません。安全ですか?
Testclass():sources(new int[32]){}
それ以外の:
Testclass(){
sources = new int[32];
}
これはコンパイルされますが、他のコードでは見たことがありません。安全ですか?
Testclass():sources(new int[32]){}
それ以外の:
Testclass(){
sources = new int[32];
}
使用する:
Testclass():sources(new int[32]){}
これは、メンバーを初期化するための推奨される方法であるmember-initialization-listを使用しています。
「安全」または「大丈夫」とは、例外安全かどうかという意味ですか?new
bad_alloc例外をスローした場合はどうなりますか?
その場合、コンストラクター本体が実行されないため、オブジェクトが完全に構築されていないため、デストラクタは呼び出されません。初期化リストのリソースを取得した場合は、リソースリークが発生する可能性があります。
このことを考慮、
class X
{
int *ints; // Order of declaration matters!
Huge *huges; // It ensures that huges will be initialized after ints
X() : ints(new int[32]), huges(new Huge[10000]) {}
};
例外をスローするとnew Huge[10000]
、に割り当てられたメモリints
がリークします!
このような場合、function-try-blockが役立ちます。これらを参照してください:
この例外安全性の問題について考えると、クラスが1つのリソースのみを管理する場合、作業が楽になることがすぐにわかります。1つのクラスが複数のリソースを管理している場合、member-initialization-listで例外をスローしたクラスを決定できず、その結果、割り当てを解除するクラスを決定できません。catch
function-try-blockのブロック。リソースリークは運命づけられています。
ただし、クラスに複数のリソースが必要な場合は、最初に、異なるタイプの各リソースをクラスにカプセル化し、これらのリソース管理クラスのオブジェクトをクラスのメンバーとして宣言します。
コンストラクターの初期化子リストで try/catch ブロックを使用するために奇妙な C++ 構文を使用しても問題ありません。
class C {
int *n;
public:
C();
};
C::C()
try : n(new int[100])
{
// do stuff here
}
catch(...)
{
// handle exceptions
}
int main()
{
C c; // Should be safe...
}