0

私はしばらくの間boost::Variantを使用してきましたが、今はそれが内部的にどのように機能するかを理解しようとしています。簡単なテストを書いたのですが、結果がわかりません。これが(簡略化)です

struct my_type
{
    my_type(){ cout << (size_t)this << " construction"; }
    ~my_type(){ cout << (size_t)this << " destruction"; }
};

int main()
{
    variant<int, my_type> x;
    x = my_type();
}

そのようなプログラムの出力は

140736940365327 construction  <-- A
140736940365236 destruction  <-- ?
140736940365327 destruction  <-- A
140736940365332 destruction  <-- ?

なぜデストラクタはコンストラクタほど何度も呼び出されないのですか?デストラクタがヒープを介して呼び出されるため、これはセグメンテーション違反ではない可能性があることを認識していますが、この動作は危険であるように思われます。私は何かが足りないのですか?これは、boost :: Variantの「バックアップ」メカニズムに関連していますか?

4

1 に答える 1

2

デフォルトのコンストラクターを定義するだけですが、もちろん、コンストラクターはさまざまなパラメーターを使用して呼び出すこともできます。コピーコンストラクター(をとるコンストラクター)を明示的に定義しないためconst my_type&、コンパイラーは暗黙的にコピーコンストラクターを生成します。独自のコピーコンストラクターを追加すると、他の2つの不思議なオブジェクトを構築するために使用されていることがわかります。

struct my_type
{
  my_type(){ cout << (size_t)this << " construction"; }
  my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
  ~my_type(){ cout << (size_t)this << " destruction"; }
};

実際、C ++ 11コンパイラを使用している場合、暗黙的に生成された移動コンストラクターがいくつかの新しいオブジェクトを担当します。上記のようにコピーコンストラクターを指定すると、暗黙の移動コンストラクターは生成されなくなるため、すべてコピーコンストラクターとして表示されます。ただし、moveコンストラクターも提供すると、次のように呼び出されます。

struct my_type
{
  my_type(){ cout << (size_t)this << " construction"; }
  my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
  my_type(my_type&&){ cout << (size_t)this << " move construction"; }
  ~my_type(){ cout << (size_t)this << " destruction"; }
};
于 2013-02-23T12:24:47.617 に答える