I have the following code:
#include
using std::cin; using std::cout; using std::endl;
#include
using std::vector;
class Quote {
As per C++ language open standard draft n3690.pdf regarding vector capacity. Please see the bold italicized statement.
23.3.7.3 vector capacity [vector.capacity] size_type capacity() const noexcept; 1 Returns: The total number of elements that the vector can hold without requiring reallocation. void reserve(size_type n); 2 Requires: T shall be MoveInsertable into *this. 3 Effects: A directive that informs a vector of a planned change in size, so that it can manage the storage allocation accordingly. After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise. "Reallocation happens at this point if and only if the current capacity is less than the argument of reserve()". If an exception is thrown other than by the move constructor of a non-CopyInsertable type, there are no effects
Also from Scott Meyers "Effective C++ Digital Collection: 140 Ways to Improve Your Programming", under item 14 Item 14.
Use reserve to avoid unnecessary reallocations. One of the most marvelous things about STL containers is that they automatically grow to accommodate as much data as you put into them, provided only that you don't exceed their maximum size. (To discover this maximum, just call the aptly named max_size member function.) For vector and string, growth is handled by doing the moral equivalent of a realloc whenever more space is needed. This realloc-like operation has four parts: 1. Allocate a new block of memory that is some multiple of the container's current capacity. In most implementations, vector and string capacities grow by a factor of between 1.5 and 2 each time.
As suggested by "songyuanyao" one should reserve the size(if it is known in advance) to avoid frequent reallocation.
When the push_back is called at the 2nd time, reallocation happened. (More precisely it happens when the new size()
is greater than capacity()
.) Then the old underlying storage of the vector
will be destroyed and the new one will be allocated, and elements need to be copied to the new storage, which cause the copy constructor to be called.
You can use reserve to avoid reallocation. e.g.
vector<Quote> basket;
basket.reserve(2);
basket.push_back(Quote("0-201-82470-1", 50));
basket.push_back(Quote("0-201-82XXXXX", 30)); // no reallocation here