为什么向量保持类类型会在push_back()时再调用复制构造函数一次? [英] Why vector hold a class type will call the copy constructor one more time when push_back()?

查看:111
本文介绍了为什么向量保持类类型会在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆