3

メンバー初期化子リストを使用したコードの例。

#include <memory>

struct Throwable
{
    Throwable()
    {
        throw "Exception!";
    }
};

struct A
{
    A() : t(Throwable()), i(new int()) {}

    Throwable t;
    std::unique_ptr<int> i;
};

次の評価順序が考えられる場合、メモリ リークが発生する可能性はありますか?

  1. new int()
  2. Throwable()
  3. t()
  4. i()

標準の順序は何ですか? いくつかのルールがあります。

https://en.cppreference.com/w/cpp/language/initializer_list

3) 次に、非静的データ メンバがクラス定義の宣言順に初期化されます。

そのtため、前に構築されiます。

https://en.cppreference.com/w/cpp/language/eval_order

9) 組み込みコンマ演算子の最初 (左) の引数の,すべての値の計算と副作用は、2 番目 (右) の引数のすべての値の計算と副作用の前に並べられます。

ただし、前の参照のため、メンバー初期化子リストはすべてのコンマ規則を使用していません。また、コンマ演算子ではありません ( https://en.cppreference.com/w/cpp/language/operator_other#Built-in_comma_o​​perator )。

10) リスト初期化では、与えられた初期化子句のすべての値の計算と副作用は、中括弧で囲まれたカンマ区切りの初期化子のリストでそれに続くすべての初期化子句に関連付けられたすべての値の計算と副作用の前に並べられます。

そしてhttps://en.cppreference.com/w/cpp/language/list_initialization

リストの初期化は、次の状況で実行されます。

5) ブレース初期化リストが使用されている場合、コンストラクターのメンバー初期化子リスト内

別のケースがあります。

メンバー初期化子リストで引数評価の順序を定義するルールを提供できますか?

4

2 に答える 2

0

次の評価順序が考えられる場合、メモリ リークが発生する可能性はありますか?

答えはノーだ、

非静的メンバーの初期化の順序は、メンバー初期化子リストの順序とは関係なく、クラス定義内のメンバー宣言の順序と同じように定義されているため、それを達成するには、構築の逆の順序で破壊を実行する必要があるためです。 、破壊が始まるときに従うべきルールでなければなりません。それに関しては、他のメンバーの前に throwable 型のメンバーを宣言したため、最初に構築され、ヒープ割り当てが発生する前にスローされます。漏れはありません。

しかし、unique_pointer 宣言の後に throwable 型のメンバーを宣言すると、初期化プロセスで最初にヒープ割り当てが行われ、その後、throwable コンストラクターから例外がスローされると、A の構築が停止し、キャッチされても、例外ハンドラーの後で例外が再スローされます。実行されますが、構築されたクラス メンバーも破棄されるという規則に従って、unique_pointer のリソース管理機能により、このシナリオでもリークが防止されます。

この小さな観察がお役に立てば幸いです。

于 2018-07-29T00:52:57.867 に答える