class a
{
object guest;
}
a::a() : guest(required_argument)
{
}
問題は、クラスのオブジェクトを作成した後にゲストのコンストラクターを呼び出す必要があることです。それを行う方法はありますか?
class a
{
object guest;
}
a::a() : guest(required_argument)
{
}
問題は、クラスのオブジェクトを作成した後にゲストのコンストラクターを呼び出す必要があることです。それを行う方法はありますか?
guest
オブジェクトとして保持したい場合は、いいえ。
自由にポインタにすることができる場合は、遅延初期化を使用できます。
本当の問題は、なぜguest
のコンストラクターの後に のコンストラクターを呼び出す必要があるのかということa
です。
guest
は の一部であるため、のコンストラクターの後にa
そのコンストラクターを呼び出すことは、 という点で矛盾しています。オブジェクトは、そのすべてのサブオブジェクトが完全に構築されている場合にのみ完全に構築されます。したがって、のコンストラクターの実行を完了することは、 の実行を完了することを意味しますのコンストラクタ。 a
a
guest
もちろん、これは、 の構築guest
中にdefault-construct して後で別の値を割り当てることができないという意味ではありません。また、 の構築中にオブジェクトをまったく構築しa
たくない場合は、ポインターを使用することもできます (より良い方法はスマート ポインタの場合) と の間の関連付けをモデル化します。guest
a
a
object
が後guest
に構築される理由は、の構築には の機能が必要だからだと思います。この場合、その機能を の前に構築された別のクラスにアウトソーシングできます。したがって host
host
guest
guest
class some_interface { /* some abstract functionality needed by guest::guest() */ };
class guest
{
public:
guest(some_interface const&); // calls pure virtual functions of some_interface
/* more stuff */
};
class host_interface : public some_interface
{
/* implements pure virtual methods of its base */
};
class host
{
host_interface _interface;
guest _guest;
public:
host(...)
: _interface(...)
, _guest(_interface)
{}
/* more stuff */
};
次の素朴な実装は失敗することに注意してください
class host : some_interface
{
/* some_data */
guest _guest;
public:
host(...)
: some_data(...)
, _guest(*this)
{}
/* more stuff */
};
にthis
渡されたときに はまだ構築されておらず、純粋仮想関数が呼び出されるためです (コンパイラがこれを検出できたはずなのに、guest::guest()
このバグが一度発生し、「純粋仮想関数が呼び出されました」という実行時エラーが発生しました)。 )。