开发者

Behaviour of container std::set during Insertion?

开发者 https://www.devze.com 2023-03-21 03:27 出处:网络
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 cal

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 = &comp;
      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;
0

精彩评论

暂无评论...
验证码 换一张
取 消