With is code, I've got the following output:
A::A() is called
test #1
A::A(const A & other) is called
test #2
A::A(const A & other) is called
A::A(const A & other) is called
test #3
A::A(const A & other) is called
A::A(const A & other) is called
A::A(const A & other) is called
When debugging the code, for the 3 test cases, I found that the 1st invocation to copy constructor is the same (and I think it makes sense): make a copy of the object and push to the vector.
However, additional invocation to the copy constructor is made through "_Umove_if_noexcept".
For test #2, when vec already has ONE entry, it will further invoke ONE time of the copy constructor.
For test #3, when vec already has TWO entry, it will further invoke TWO times of the copy constructor.
This is reproducible on Visual Studio 2017 and gcc 5.4.0.
Why is this happening? Is there a performance issue?
Thanks
#include <iostream>
#include <vector>
class A
{
public:
//constructor
A()
{
a = 10;
std::cout << "A::A() is called" << std::endl;
}
//copy constructor
A(const A& other) : a(other.a)
{
std::cout << "A::A(const A & other) is called" << std::endl;
}
//assignment operator
A& operator=(const A& other)
{
std::cout << "A::operator=(const A & other) is called" << std::endl;
a = other.a;
return *this;
}
public:
int a;
};
int main()
{
std::vector<A> vec;
//A::A() is called
A a;
std::cout << "test #1" << std::endl;
//A::A(const A & other) is called by push_back
vec.push_back(a);
std::cout << "test #2" << std::endl;
//A::A(const A & other) is called
//A::A(const A & other) is called from _Umove_if_noexcept
vec.push_back(a);
std::cout << "test #3" << std::endl;
//A::A(const A & other) is called
//A::A(const A & other) is called from _Umove_if_noexcept
//A::A(const A & other) is called from _Umove_if_noexcept
vec.push_back(a);
std::cin.get();
return 0;
}
vector::push_back() push_back() function is used to push elements into a vector from the back. The new value is inserted into the vector at the end, after the current last element and the container size is increased by 1.
Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector.
You call the function by value and do two copies inside.
C++ push_back() is a pre-defined function that is used to insert data or elements at the end of the vector or it pushes the element in the vector from the back.
First of all you have to remember that unless you reserve memory for the vector, it needs to allocate and reallocate memory as its capacity needs to increase.
The reallocation basically allocates new memory, then copies the element in the vector to the new memory.
Furthermore, when you push a value into a vector, that value needs to be copied into the vector. You can avoid that by emplacing the value (which means it's constructed in place in the vector), or by moving the value when you push it back.
The first copy is clear - the push_back() needs to copy the object.
In the second copy, two things happen:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With