A copy constructor of class T is a non-template constructor whose first parameter is T&‍, const T&‍, volatile T&‍, or const volatile T&‍, and either there are no other parameters, or the rest of the parameters all have default values.

from cppreference.com

## When is copy constructor called?

In C++, a Copy Constructor may be called in following cases:

• When an object of the class is returned by value.
• When an object of the class is passed (to a function) by value as an argument.
• When an object is constructed based on another object of the same class.
• When compiler generates a temporary object.

Let’s talk about some cases where you might not even realize how many copies it has done. Copy is not cheap, sometimes. In some cases, copy constructor can be avoided by Copy Elision, but it is not in the scope of this discussion.

## Show me an example

How many times the copy constructor is called?

The answer is 3.

• When i is 0, it creates a new Point object, calls normal constructor.
• Pushes it into vector, copy once.
• When i is 1, it creates a new Point object again, calls normal constructor.
• Pushes again, copy again.
• Wait, before push, vector points needs to resize (usually double the size), copy points[0] to new vector first, then push.
• In total, 3 copy constructor calls and 2 normal calls.

You can run this code online, https://onlinegdb.com/BkuZ6vFB7. Play with it, change n to some other value to see if you can get the right number of copy constructor calls.

## Can we do better?

Yes, we can use std::vector::emplace_back() instead of std::vector::push_back().

(It) Appends a new element to the end of the container. The element is constructed through std::allocator_traits::construct, which typically uses placement-new to construct the element in-place at the location provided by the container.

from cppreference.com

Let’s change the main().

How many times does copy constructor get called? Only once.

• When i is 0, emplace_back calls the normal constructor of Point, put the newly created object in vector directly. no copy.
• When i is 1, points resizes itself, need to copy the existing element points[0], one copy.
• Then, as the first step, emplace_back creates new object in place, no copy needed.

You can also run the code online, https://onlinegdb.com/SJo_lOKSX. Change n to some other values to see if you can get the right number of copy constructor calls.

## Should I always use emplace_back()?

We can not deny the fact that std::vector::emplace_back() saves unnecessary copy operations and it can be a big win for some operations on large objects. However, using emplace_back means you need to take care of the constructor arguments, which sometimes could be arbitrary. Check the example in Tip of the Week #112: emplace vs. push_back, the second example constructs a vector of over a million elements, allocating several megabytes of memory in the process, if the variable type is not as what you think, and this is dangerous.

For more expensive types, this may be a reason to use emplace_back() instead of push_back(), despite the readability and safety costs, but then again it may not. Very often the performance difference just won’t matter. As always, the rule of thumb is that you should avoid optimizations that make the code less safe or less clear, unless the performance benefit is big enough to show up in your application benchmarks.

Let’s keep this in mind.