8

これはコンパイルされますが、他のコードでは見たことがありません。安全ですか?

Testclass():sources(new int[32]){}

それ以外の:

Testclass(){
    sources = new int[32];
}
4

2 に答える 2

14

使用する:

Testclass():sources(new int[32]){}

これは、メンバーを初期化するための推奨される方法であるmember-initialization-listを使用しています。

「安全」または「大丈夫」とは、例外安全かどうかという意味ですか?newbad_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で例外をスローしたクラスを決定できず、その結果、割り当てを解除するクラスを決定できません。catchfunction-try-blockのブロック。リソースリークは運命づけられています。

ただし、クラスに複数のリソースが必要な場合は、最初に、異なるタイプの各リソースをクラスにカプセル化し、これらのリソース管理クラスのオブジェクトをクラスのメンバーとして宣言します。

于 2013-02-04T06:55:44.283 に答える
1

コンストラクターの初期化子リストで 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...
}
于 2013-02-04T08:25:13.557 に答える