copy constructor

Why copy constructor and destructor called 3 times each when I call insert in the following code?

#include <iostream>
#include <map>
using namespace std;

class ABC
{

int x;
int y;

public:
ABC()
{
x =0; y = 0;
cout <<"ctor called\n";
}

ABC(const ABC& abc)
{
x = abc.x;
y = abc.y;

cout << "Copy ctor called\n";
}

~ABC()
{
cout <<"dtor called\n";
}

};


int main()
{
ABC a;
map<int, ABC> testmap;
testmap.insert(pair<int, ABC> (0, a));
return 0;
}
Last edited on
I think there must be two copies on the testmap.insert line

One to make the temporary pair object and another copy arising from the insert method

Have you tried turning on compiler optimisation to see if the compiler can bypass the temporary?

on g++ there are -O2 and -O3 to try out

(do you mean one constructor and two copy constructors rather than 3 copy constructors)
I was going to say this:
(do you mean one constructor and two copy constructors rather than 3 copy constructors)

but mik2718 got there first
(do you mean one constructor and two copy constructors rather than 3 copy constructors)
but mik2718 got there first


No. That's wrong. The following is the output.

ctor called
Copy ctor called
Copy ctor called
Copy ctor called
dtor called
dtor called
dtor called
dtor called

on g++ there are -O2 and -O3 to try out


O2 and O3 doesn't make any change.
Compiler specific :

GCC and MSVC 2008 gives:

ctor called
Copy ctor called
Copy ctor called
Copy ctor called
dtor called
dtor called
dtor called
dtor called



MSVC 2010 gives :

ctor called
Copy ctor called
Copy ctor called
dtor called
dtor called
dtor called
This line testmap.insert(pair<int, ABC> (0, a)); can generate 3 ABC copy constructors
as follows:

1. the variable a is copied to pass to the pair constructor.

2. The pair object created is step 1 above is then copied to pass map.insert function.
(This means that the ABC copy constructor is called on the ABC object contained in the pair)

3. The insert function copies the pair object passed to it.
(hence the pair object is copied which means that the ABC copy constructor is called againis copied again)


So there are 3 copy constructor calls.

EDIT:
In the case of MSVC2010 and the 2 copy constructors - VC2010 is using the move semantics from the new C++0x standard which allows it to eliminate 1 copy constructor call ( one less call to the pair copy constructor, which means one less call to the ABC copy constructor).

**I still don't understand this new move semantisc stuff yet though**

Last edited on
The STL containers are known for doing copying. If I remember right, to use them, your class must be default constructable and copyable. I don't think this varies by compiler, but rather varies by standard library implementation.
AFAIK the STL doesn't ask for defaults constructors.
Well one exception is operator[] for maps, that calls
insert( make_pair( key, T() ) )
But you have the same functionallity with find and insert
Last edited on
2. The pair object created is step 1 above is then copied to pass map.insert function.
(This means that the ABC copy constructor is called on the ABC object contained in the pair)

3. The insert function copies the pair object passed to it.
(hence the pair object is copied which means that the ABC copy constructor is called againis copied again)


Your 2nd and 3rd step are the same. I got the answer from another place. The third copy is created in the insert itself. The map is implemented as a binary tree. In order to add the pair to the tree, the pair is copied again, which calls the copy ctor for the third time.

If you pass a reference or a pointer to the object of ABC, all the three copy ctor calls can be eliminated.
Your 2nd and 3rd step are the same. I got the answer from another place. The third copy is created in the insert itself. The map is implemented as a binary tree. In order to add the pair to the tree, the pair is copied again, which calls the copy ctor for the third time.


no they aren't - you either miread or misunderstood what I was saying.
Topic archived. No new replies allowed.