在向量中插入数据时,复制构造函数多次调用

时间:2011-06-09 17:03:41

标签: c++

#include <iostream>
#include <vector>
using namespace std;
class base
{
    int x;
public:
    base(int k){x =k; }
    void display()
    {
        cout<<x<<endl;
    }

    base(const base&)
    {
        cout<<"base copy constructor:"<<endl;
    }
};
int main()
{
    vector<base> v;
    base obase[5]={4,14,19,24,29};
    for(int i=0; i<5; i++)
    {
        v.push_back(obase[i]);
    }

}

将数据插入向量时,使用复制构造函数将复制到该数据转到向量。

当我运行此程序时,

  1. 对于第一次插入(i = 0),调用一次复制构造函数。
  2. 对于第二次插入(i = 1),称为两次复制构造函数
  3. 对于第三次插入(i = 3),称为三次复制构造函数
  4. 对于第四次插入(i = 3),称为复制构造函数的四次
  5. 对于第五次插入(i = 4),称为五次复制构造函数
  6. 请有人告诉我为什么会这样吗?对于每次插入,不应该只调用一次复制构造函数吗?

3 个答案:

答案 0 :(得分:7)

调用push_back()会根据需要增加向量的大小,这涉及复制向量的内容。既然你已经知道它将包含五个元素,在循环之前要么v.reserve(5);,要么使用范围构造函数:

base obase[5]={4,14,19,24,29};
vector<base> v(obase, obase+5);

答案 1 :(得分:3)

您的复制构造函数存在缺陷,您忘记实际复制数据:)

base(const base& that) : x(that.x)
{
    cout << "base copy constructor\n";
}

此外,如果您有一个现代编译器,您可以编写一个移动构造函数并学习新的东西:

base(base&& that) : x(that.x)
{
    cout << "base move constructor\n";
}

答案 2 :(得分:2)

如果v需要调整其内部缓冲区的大小,它通常会分配一个全新的内存区域,因此需要将以前在向量中的所有对象复制到新位置。这是使用常规复制完成的,因此调用了复制构造函数。

如果您可以估算出需要多少元素,则应该在向量上调用reserve()以预先保留存储空间。

请注意,std::vector的调整大小/增长行为与实现有关,因此您的代码示例将使用不同的标准库实现产生不同的结果。