为什么向量保持类类型会在push_back()时再调用复制构造函数一次? [英] Why vector hold a class type will call the copy constructor one more time when push_back()?
问题描述
我有以下代码:
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <vector>
using std::vector;
class Quote {
public:
Quote() = default;
Quote(const std::string &book, double sales_price):
bookNo(book), price(sales_price) { }
// Quote(const Quote&) = default; // memberwise copy
Quote(const Quote &orig): bookNo(orig.bookNo), price(orig.price) {
cout << orig.isbn() << endl;
cout << "called Quote(const Quote &)" << endl;
}
Quote& operator=(const Quote&) = default; // copy assign
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n) const
{ cout << "Quote::net_price\n"; return n * price; }
virtual void debug() const { cout << bookNo << ' ' << price << endl; }
virtual ~Quote() = default;
private:
std::string bookNo; // ISBN number of this item
protected:
double price = 0.0; // normal, undiscouted price
};
int main(int argc, char *argv[]) {
vector<Quote> basket;
basket.push_back(Quote("0-201-82470-1", 50));
basket.push_back(Quote("0-201-82XXXXX", 30));
cout << "\ntraverse bakset" << endl;
for (const auto &v : basket)
v.debug();
}
编译上面的代码并运行后,结果是:
After I compile the above code and run, the result is:
0-201-82470-1
called Quote(const Quote &)
0-201-82XXXXX
called Quote(const Quote &)
0-201-82470-1
called Quote(const Quote &)
traverse bakset
0-201-82470-1 50
0-201-82XXXXX 30
根据复制构造函数的时间被调用,它会被两次调用,因为当我 push_back()
到一个向量时,我只是推了两个元素。但是为什么在上面的结果中显示被调用了三次。
但是,根据 main
中的for循环,向量的元素是正确的。
According to when copy constructor is called, it will be called twice because I just have pushed two elements when I push_back()
to a vector. But why it is called three times displayed in the above result.
However, according to the for-loop in main
, the element of the vector is right.
为什么将复制构造函数推入向量时又调用一次?我定义的副本构造函数有什么问题吗?
Why the copy constructor is called one more time when pushed to a vector? And is there anything wrong with my defined copy constructor?
推荐答案
当 push_back 。 (更确切地说,当新的 size()
大于 capacity()
时,就会发生这种情况。)然后,旧的基础存储 vector
中的一个将被销毁并分配新的,并且需要将元素复制到新的存储中,这将导致调用复制构造函数。
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
这篇关于为什么向量保持类类型会在push_back()时再调用复制构造函数一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!