1
class Monitor {
public:
    Monitor(string someData);
    Person person_;
}

class Person {
public:
    Person(string personId);
}

Personにはデフォルトのコンストラクターはありません。引数コンストラクターが1つあります。Monitorコンストラクターでのみ初期化できます。私はJavaから来ており、宣言はポインタのみであるため、宣言するときに新しいインスタンスを初期化する必要はありません。

デフォルトのコンストラクターを持たないクラスメンバーのベストプラクティスは何ですか?デフォルトのコンストラクターを追加するか(欠点-使用しない)、ポインターを使用する必要があります。

4

1 に答える 1

7

はい、できます。コンストラクタ初期化子リストを使用して、常にそうする必要があります。

class Monitor
{
    Person p; 
    bool   state;
    const  int n;
    double & d;

    Monitor(std::string const & pname, double & dbl)
    : p(pname)
    , state(false)
    , n(some_other_function(p, state))
    , d(dbl)
    {
         // constructor body should be as short as possible
    }

    // ...

};

ご覧のとおり、初期化は単なる仕掛けではありません。むしろ、C ++型システムの重要な必要性です。定数や参照など、初期化する必要があり、割り当てることができない変数がたくさんありますが、デフォルトのコンストラクターがないユーザー定義型もあります。(デフォルトのコンストラクターがあったとしても、代入演算子が必要になります。いずれにせよ、少し後で上書きしたくないものを作成するのは無駄です。)

クラス構成要素が構築される順序にも注意してください。クラスの新しいインスタンスを作成する場合、メンバーオブジェクトは、クラス定義で宣言されている順序で最初に構築されますが、で指定されているように初期化されます。イニシャライザリスト。すべてのメンバーが構築された後、コンストラクターの本体が実行されます。

実際、メンバーオブジェクトの前に構築されるもう1つのものがあります。それは、ベースサブオブジェクトです。当然、それらの初期化子も初期化子リストに含まれます。

struct Foo { Foo(int, bool);               /* ... */ };
struct Bar { Bar(std::string const &, int) /* ... */ };

class Monitor : public Foo, private Bar
{
    Person p;

    Monitor(std::string const & pname, int a, int b)
    : Foo(a, a == b)
    , Bar(pname, b)
    , p(pname)
    {
        // constructor body
    }

    // ...
};

コンストラクター初期化子リストに、実行されるのと同じ順序で初期化子を書き込むことを強くお勧めします(強制ではありません)。

于 2012-09-18T08:33:52.753 に答える