2011-09-23 10 views
16

folowingコードは期待できない出力を示しています。STL Vectorは割り当てられていないオブジェクトのデストラクタを呼び出していますか?

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created" << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed" << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

それが示して実行すると:

Created-1077942161 
Destroyed-1077942161 
Destroyed674242816 

は、私は2番目の「破壊」の出力はすべきではないと思います。ベクトルを使用しない場合、結果は1つのCreatedと1つのDestroyed行が予想どおりになります。この動作は正常ですか?

それがあるべきよう

+3

+1 [SSCCE](http://sscce.org/) – Flexo

+3

ポインタを出力するには、voidポインタにキャストすることをお勧めします。 'std :: cout <<(void *)this << std :: endl ; '。 –

+0

また、 'EXIT_SUCCESS'を返すことはオプションです。戻り値を 'main'で省略すると、' 0'が返されます(どちらの数字があなたのプラットフォームで「正常終了」を意味するか)。 –

答えて

31

すべてがある(これはFreeBSDシステム上でGCCでコンパイルされている):main()の終わりに作成され、破棄されますローカル変数tが、そこだとなっており、v[0]がありますmain()の終わりに作成され、破棄されました。

v[0]の作成が表示されません。これは、テストクラスが提供していないコピーまたは移動コンストラクタによって発生するためです。 (だから、コンパイラはなく、出力せずに、あなたのための1を提供します。)テストのため


を一度、すべての可能なすべてのコンストラクタが含まれているテストクラス、デストラクタ、代入とスワップ事業者のために自分自身のために書くために便利ですそれぞれに診断行を出力するので、コンテナやアルゴリズムで使用されたときのオブジェクトの動作を目で見ることができます。

+0

'コンストラクタを移動する 'ことはできません。 – Nawaz

+0

@Namaz:そうです。移動コンストラクターを使用するには、eitehr 'v.push_back(std :: move(t))'または 'v.push_back(test())'と言う必要があります。しかし、両方とも同様の一連のメッセージを作成します。 –

29
#include <cstdlib> 
#include <vector> 
#include <iostream> 

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created " << (long)this << std::endl; 
    } 
    test(const test&) 
    { 
     std::cout << "Copied " << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed " << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

出力:

Created -1076546929 
Copied 147865608 
Destroyed -1076546929 
Destroyed 147865608 

std::vector::push_backコピーtオブジェクト、あなたは上記のコードによって呼び出されているコピーコンストラクタを見ることができます。

2

ベクターにはtのコピーが保存されていますので、push_backを呼び出した後、tという2つのバージョンがあります。スタックに1つ、ベクターに1つあります。ベクターバージョンはコピーコンストラクタによって作成されているので、そのオブジェクトの "Created ..."プロンプトは表示されませんが、ベクターコンテナがスコープから外れた場合でも破壊されなければならないため、 "Destroyed ..."というメッセージ。

関連する問題