5

次の C++ クラスを検討してください。

struct Point
{
    int x;
    int y;

    explicit Point() =default; // 1
    explicit Point(int x_, int y_): x(x_), y(y_) { } // 2
};

Point2 番目のコンストラクターは、特定xの値を持つを作成するのに役立ちyます。最初のものは存在するので、デフォルトでPoint. ただし、効率化のため、defaulted には設定されずxyゼロに設定されます。すべてのメンバーをゼロに設定したい場合は、別のコンストラクターを使用できます。

explicit Point(int val) : x(val), y(val) { } // 3

このようにして、 をデフォルトで初期化するかPoint、すべてのメンバーをゼロに設定して初期化するかを選択できます。

Point p1;    // Don't initialize members.
Point p2(0); // Initialize all members to zero.

3 番目のコンストラクターの問題は、ゼロだけでなく、実際には任意の値を渡すことができることです。例えば:

Point p(1); // Both x and y set to 1! Is this the intent? If so,
            // probably should have used Point p(1, 1) instead.

別の方法は、ゼロまたはデフォルト値を表す特別な型を持ち、それをコンストラクターに渡すことです。

explicit Point(Default) : x(0), y(0) { } // 4

WhereDefaultは次のように簡単に定義できます。

struct Default { };

次に、いつPointデフォルト値で初期化するかを制御できます。

Point p1;            // Don't initialize members.
Point p2(Default()); // Initialize members with default values.

Defaultセンチネル型のメソッド(4 番) と、単一の値を取り、すべてのメンバーをその値に初期化するコンストラクター (3 番) のどちらのメソッドが優れていると考えられますか? 2つの方法の長所/短所は何ですか? または、これを行うための別のより良いメカニズムはありますか?

編集:この単純なクラスは説明のために選択されていることに注意してください。実際には、 「初期化済み」と見なされる特定のデフォルト値が必要なメンバーがさらに多く存在する可能性があります。

4

3 に答える 3

2

これに関して私が目にする最も一般的な方法は、必要なデフォルト値に設定されたクラスのすべてのメンバーを含む初期化リストを使用して、引数なしのコンストラクターを実装することです。

Point(): x(0), y(0) { }

この背後にある理由は、メンバーを何らかの既知の値に初期化せずにオブジェクトをインスタンス化することはおそらくないため、実際にはその既定のコンストラクターを存在させたくないということです。

于 2016-12-04T18:58:44.520 に答える