2017-09-27 7 views
0

マルチマップでオブジェクトをキーとして使用しています。私はクラスデータのインスタンスが1つだけです:Data d1(1,2)。出力においてマルチマップでオブジェクトをキーとしてオブジェクトを使用すると、デストラクタが十分に呼び出される理由

#include <iostream> 
#include <string> 
#include <map> 

using namespace std; 

class Data{ 
    public: 
     static int counter; 
     Data(int x = 0, int y = 0):_x(x),_y(y){counter += 1; cout <<"constructor call " << counter << endl;} 

     virtual ~Data() 
     { 
      counter -= 1; 
      cout <<"calling destructor " << counter << endl; 
     } 

     bool operator<(const Data & right) const{ 
      return _x < right._x && _y < right._y; 
     } 
    private: 
     int _x; 
     int _y; 
}; 

int Data::counter = 0; 

int main() 
{ 
multimap<Data, string> m_map; 

Data d1(1,2); 
m_map.insert(make_pair(d1, "1")); 

return 0; 
} 

デストラクタを3回呼び出されています。

constructor call 1 
calling destructor 0 
calling destructor -1 
calling destructor -2 
+2

コピーコンストラクタにもログを追加します。 – doctorlove

+0

..と移動コンストラクタ。移動したオブジェクトはまだ破壊されています。 – MSalters

答えて

3

複数のインスタンスがあります。

class Data { 
public: 
    static int counter; 
    Data(int x = 0, int y = 0) :_x(x), _y(y) { counter += 1; cout << "constructor call " << counter << endl; } 
    Data(const Data & other) :_x(other._x), _y(other._y) { counter += 1; cout << "copy constructor call " << counter << endl; } 

    virtual ~Data() 
    { 
     counter -= 1; 
     cout << "calling destructor " << counter << endl; 
    } 

    bool operator<(const Data & right) const { 
     return _x < right._x && _y < right._y; 
    } 
private: 
    int _x; 
    int _y; 
}; 

これは、コピーコンストラクタも呼び出されていることを示します。

+0

はいそうですが、あなたが@doctorlove感謝 コンストラクタ呼び出し1つの コピーコンストラクタ呼び出し2 コピーコンストラクタ・コール呼び出し3 デストラクタを呼び出す2 デストラクタデストラクタ0 –

+1

は、3/5 /ゼロのルールを見上げて呼び出す1 - あなたはデストラクタを書く場合あなたはしばしばコピーコンディションと割り当て(と移動)を考慮する必要があります – doctorlove

+0

私は、移動コンストラクタを使用します。それはまた呼び出される。 @Sam Varshavchikのように私はそれを辿る必要があります。 –

2

他の2つのデストラクタ呼び出しは、最初にコピーを作成した一時オブジェクトを破棄することです。明示的なコピーコンストラクタをオブジェクトに追加すると、それが呼び出されます。

コピーコンストラクタが呼び出される理由を理解するには、std::map::insertのパラメータがstd::pairであることに注意してください。ここで、実際に発生する一連のイベントが発生するためには、実際に何が起こらなければならないのかを考えてみましょう。std::pairあなたのオブジェクトを含んでいます。このstd::pairが実際のマップに挿入されるようにします。

さらに理解と理解を深めるために、デバッガを使用してコピーコンストラクタにブレークポイントを設定し、ブレークポイントがヒットするたびにスタックトレースを調べます。

関連する問題