在插入集合时,集合内部是否多次删除了一些对象?我尝试插入两个MyClass类型的对象,如下面的程序,但令我惊讶的是它调用类的析构函数,最初插入值为2次!我无法理解这背后的任何逻辑。任何人都可以对输出有所了解吗? (突出显示为粗体)
#include<stdio.h>
#include<stdlib.h>
#include<set>
using namespace std;
struct MyClass
{
double num;
~MyClass()
{
printf("Destructor called..for val: %lf\n", num);
}
};
typedef int (*fun_comp)(MyClass, MyClass);
int
comp(MyClass a, MyClass b)
{
return a.num-b.num;
}
int
main()
{
fun_comp fptr;
fptr = ∁
set<MyClass, int (*)(MyClass, MyClass)> b(fptr);
for(int i=3; i< 5; i++)
{
printf("started with i: %d....\n\n", i);
{
MyClass m;
m.num=i*1.134;
b.insert(m);
printf("Inserted val: %lf\n", m.num);
}
printf("ended....\n\n");
}
printf("Done with insert..\n");
return 0;
}
输出: 从i开始:3 ....
插入val:3.402000
destructor called..for val:3.402000
...结束
从i开始:4 ....
析构函数名为..for val:4.536000 &lt; -------为什么在插入之前取消分配
析构函数名为.for val:3.402000 &lt; -------多次调用此值对象的析构函数
析构函数名为.for val:4.536000 &lt; -------- ??
析构函数名为.for val:3.402000 &lt; ------再次!!
插入val:4.536000
destructor called..for val:4.536000
...结束
完成插入..
destructor called..for val:3.402000
destructor called..for val:4.536000
答案 0 :(得分:11)
将比较函数更改为使用(常量)引用
int comp(const MyClass& a, const MyClass& b)
{
return a.num-b.num;
}
每次调用你的comp时,都会创建a和b的副本。这些副本在退出时会被销毁。
答案 1 :(得分:11)
比较器
int
comp(MyClass a, MyClass b)
{
return a.num-b.num;
}
按值获取其参数。这将创建额外的副本,然后销毁。
通过引用传递将更好。
答案 2 :(得分:4)
除了上面提到的要点之外,您的比较函数无效,因为它没有指定值的一致排序。如果a.num = 1且b.num = 2则comp(a,b)为真,意味着“先于”b,而comp(b,a)也为真,这意味着b“在”之前“ 。这使得set的行为未定义。
最好为MyClass创建一个小于运算符,让set&lt;&gt;的默认比较函数完成工作: struct MyClass { 双数;
~MyClass()
{
printf("Destructor called..for val: %lf\n", num);
}
bool operator < (const MyClass &rhs) const
{
return num < rhs.num;
}
};
...
set<MyClass> b;