我有以下代码:
#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();
}
编译完上面的代码并运行后,结果为:
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循环,向量的元素是正确的。
为什么在推送到向量时再次调用复制构造函数?我定义的拷贝构造函数有什么问题吗?
答案 0 :(得分:3)
第二次调用push_back时,重新分配。 (更确切地说,当新的@ResponseBody
public ResponseEntity somthing() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
return new ResponseEntity<>(new Gson().toJson("hello this is my message"), headers, HttpStatus.NOT_FOUND);
}
大于size()
时会发生这种情况。)然后,capacity()
的旧底层存储将被销毁,新的存储将被分配,元素需要被复制到新存储器,这将导致调用复制构造函数。
您可以使用reserve来避免重新分配。 e.g。
vector
答案 1 :(得分:0)
根据C++ language open standard draft n3690.pdf 关于矢量容量。请参阅粗体斜体声明。
23.3.7.3载体容量[vector.capacity] size_type capacity()const noexcept; 1返回:向量可以容纳的元素总数,无需重新分配。 void reserve(size_type n); 2要求:T应为MoveInsertable到* this。 3效果:一种指令,通知向量计划的大小变化,以便它可以管理存储 相应的分配。在reserve()之后,capacity()大于或等于reserve的参数if 重新分配发生;并且等于capacity()的先前值。 “ 重新分配 此时,当且仅当当前容量小于reserve()的参数 “。如果异常 除非由非CopyInsertable类型的move构造函数抛出,否则没有效果
同样来自Scott Meyers的“有效的C ++数字馆藏:改善编程的140种方法”,项目14 第14项。
使用reserve来避免不必要的重新分配。 关于STL容器最奇妙的事情之一就是它们会自动增长以容纳您放入的数据,只要您不超过其最大尺寸即可。 (要发现这个最大值,只需调用恰当命名的max_size成员函数。)对于向量和字符串,只要需要更多空间,就可以通过执行realloc的道德等效来处理增长。这种类似realloc的操作有四个部分: 1.分配一个新的内存块,它是容器当前容量的一部分。 在大多数实现中,矢量和字符串容量每次增长1.5到2倍。
根据“ songyuanyao ”的建议,应保留大小(如果事先知道),以避免频繁重新分配。