I know STL containers like vector
copies the object when it is added. push_back
method looks like:
void push_back ( const T& x );
I am surprised to see that it takes the item as reference. I wrote a sample program to see how it works.
struct Foo
{
Foo()
{
std::cout << "Inside Foo constructor" << std::endl;
}
Foo(const Foo& f)
{
std::cout << "inside copy constructor" << std::endl;
}
};
Foo f;
std::vector<Foo> foos;
foos.push_back(f);
This copies the object and I can see it is calling copy-constructor.
My question is, when the push_back
takes item as reference, how it is calling copy-constructor? Or am I missing something here?
Any thoughts..?
They are implemented as class templates, which allows great flexibility in the types supported as elements. The container manages the storage space for its elements and provides member functions to access them, either directly or through iterators (reference objects with similar properties to pointers).
In STL, we have various types of container classes like Array, vector, queue, deque, list, map, set, etc. These containers are generic in nature and are implemented as class templates. Containers are dynamic in nature and can be used to hold various types of objects.
It probably uses "placement new
" to construct the object in-place in its internal array. Placement new
doesn't allocate any memory; it just places the object where you specify, and calls the constructor. The syntax is new (address) Class(constructor_arguments)
.
The copy constructor T::T(T const &)
is called to create the copy in-place. Something like this (simplified):
template<T>
void vector<T>::push_back(T const &item) {
// resize if necessary
new (&d_array[d_size++]) T(item);
}
Note that T
must have a copy constructor for this to work. By default (if you do nothing), it gets one for free. If you define it explicitly, it must be public
for vector<T>
to work.
Here's how GNU's libstdc++ does it, but I doubt that it'll be very enlightening. There is an allocator (the second template argument to vector
) that makes it less straightforward.
The C++ SDK always takes const T &
as function parameter for efficiency.
In your case if it take T
as parameter, the copy action will be done twice, one for passing it to function push_back(f)
, one for internal adding it to the container. And by taking const T&
as parameter only one copy is needed!
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