为什么在使用对象作为多映射中的键时,析构函数被调用得太多了
Why is destructor being called more than enough when using an object as key in a multimap
我正在使用一个对象作为多重映射中的键,如下所示。我只有 class 数据的 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
另外两个析构函数调用正在销毁最初复制构造的临时对象。向对象添加显式复制构造函数,您将看到它被调用。
要弄清楚为什么调用复制构造函数,请观察 std::map::insert
的参数是 std::pair
。现在考虑一下,为了使这一系列事件真正发生,实际必须发生什么:std::pair
正在构建,包含您的对象;并将此 std::pair
插入到实际地图中。
要获得更高层次的洞察力和理解力,请使用调试器在复制构造函数中设置断点,并在每次命中断点时检查堆栈跟踪。
您有多个实例。
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;
};
这也会显示正在调用的复制构造函数。
我正在使用一个对象作为多重映射中的键,如下所示。我只有 class 数据的 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
另外两个析构函数调用正在销毁最初复制构造的临时对象。向对象添加显式复制构造函数,您将看到它被调用。
要弄清楚为什么调用复制构造函数,请观察 std::map::insert
的参数是 std::pair
。现在考虑一下,为了使这一系列事件真正发生,实际必须发生什么:std::pair
正在构建,包含您的对象;并将此 std::pair
插入到实际地图中。
要获得更高层次的洞察力和理解力,请使用调试器在复制构造函数中设置断点,并在每次命中断点时检查堆栈跟踪。
您有多个实例。
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;
};
这也会显示正在调用的复制构造函数。