While inserting in a set, does the set internally delete some of the objects multiple times? I tried to insert two objects of type MyClass as开发者_C百科 in following program but to my surprise it calls the destructor of class with initially inserted value 2 times! I am not able to understand any logic behind this. Can anyone give some idea on the output? (highlighted as bold)
#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;
}
output: started with i: 3....
Inserted val: 3.402000
Destructor called..for val: 3.402000
ended....
started with i: 4....
Destructor called..for val: 4.536000 <------- why this is deallocated before insertion
Destructor called..for val: 3.402000 <------- multiple call to destructor for this valued object
Destructor called..for val: 4.536000 <-------- ??
Destructor called..for val: 3.402000 <------ again!!
Inserted val: 4.536000
Destructor called..for val: 4.536000
ended....
Done with insert..
Destructor called..for val: 3.402000
Destructor called..for val: 4.536000
The comparator
int
comp(MyClass a, MyClass b)
{
return a.num-b.num;
}
takes its parameters by value. This will create extra copies that are then destroyed.
Passing by reference will work better.
Change the comparison function to use (const) references
int comp(const MyClass& a, const MyClass& b)
{
return a.num-b.num;
}
Each time your comp is being called it is creating copies of a and b. These copies are being destroyed when comp exits.
In addition to the points made above, your comparison function isn't valid because it doesn't specify a consistent ordering of the values. If a.num=1 and b.num=2 then comp(a,b) is true, meaning that a "comes before" b, and comp(b,a) is also true, meaning that b "comes before" a. This makes the behavior of set undefined.
It's better to create a less-than operator for MyClass and let set<>'s default comparison function do the work: struct MyClass { double num;
~MyClass()
{
printf("Destructor called..for val: %lf\n", num);
}
bool operator < (const MyClass &rhs) const
{
return num < rhs.num;
}
};
...
set<MyClass> b;
精彩评论