2017-09-27 65 views
0

我在多图中使用对象作为关键字,如下所示。我只有一个类数据实例: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 调用析构函数1 调用析构函数0 –

+1

查找三/五类/零规则 - 如果你写一个析构函数你经常不得不考虑复制缺点,并赋值(并移动) – doctorlove

+0

当我使用移动构造函数。它也被调用。作为@Sam Varshavchik,我必须追查它。 –

2

另外两个析构函数调用正在破坏最初被复制,构建了临时对象。添加一个显式的拷贝构造函数给对象,你会看到它被调用。

要找出复制构造函数调用的原因,请注意参数std::map::insertstd::pair。现在考虑一下,为了使这一系列事件发生到实际发生中必须实际发生的事情:构造一个std::pair,包含您的对象;并将此std::pair插入到实际的地图中。

为了让您更深入地了解和理解,请使用调试器在复制构造函数中设置断点,并在每次触发断点时检查堆栈跟踪。

相关问题