Why vector hold a class type will call the copy constructor one more time when push_back()?

北战南征 提交于 2019-12-02 01:26:45

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
Gajanana

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!