0
class a
{
   object guest;
}

a::a() : guest(required_argument)
{
}

問題は、クラスのオブジェクトを作成した後にゲストのコンストラクターを呼び出す必要があることです。それを行う方法はありますか?

4

3 に答える 3

5

guestオブジェクトとして保持したい場合は、いいえ。

自由にポインタにすることができる場合は、遅延初期化を使用できます。

于 2013-01-06T18:02:32.700 に答える
2

本当の問題は、なぜguestのコンストラクターの後に のコンストラクターを呼び出す必要があるのか​​ということaです。

guestは の一部であるため、のコンストラクターの後にaそのコンストラクターを呼び出すことは、 という点で矛盾しています。オブジェクトは、そのすべてのサブオブジェクトが完全に構築されている場合にのみ完全に構築されます。したがって、のコンストラクターの実行を完了することは、 の実行を完了することを意味しますのコンストラクタ。 aaguest

もちろん、これは、 の構築guest中にdefault-construct して後で別の値を割り当てることができないという意味ではありません。また、 の構築中にオブジェクトをまったく構築しaたくない場合は、ポインターを使用することもできます (より良い方法はスマート ポインタの場合) と の間の関連付けをモデル化します。guestaaobject

于 2013-01-06T18:11:01.520 に答える
1

が後guestに構築される理由は、の構築には の機能が必要だからだと思います。この場合、その機能を の前に構築された別のクラスにアウトソーシングできます。したがって hosthostguestguest

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()このバグが一度発生し、「純粋仮想関数が呼び出されました」という実行時エラーが発生しました)。 )。

于 2013-01-06T18:28:01.327 に答える