在矢量中插入数据时多次调用复制构造函数
Copy constructor called many times when data is inserted in vector
#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]);
}
}
当数据插入到向量中时,使用复制构造函数将数据复制到该向量。
当我运行这个程序时,
- 对于第一次插入(i=0(,调用一次复制构造函数
- 对于第二次插入(i=1(,调用两次复制构造函数
- 对于第三次插入(i=3(,调用三次复制构造函数
- 对于第四次插入(i=3(,调用四次复制构造函数
- 对于第五次插入(i=4(,调用五次复制构造函数
请任何人告诉我为什么会发生这种事?对于每次插入,复制构造函数不应该只调用一次吗?
对push_back()
的调用会根据需要增加向量的大小,这涉及到复制向量的内容。由于您已经知道它将包含五个元素,要么是循环前的v.reserve(5);
,要么使用范围构造函数:
base obase[5]={4,14,19,24,29};
vector<base> v(obase, obase+5);
您的复制构造函数有缺陷,您忘记了实际复制数据:(
base(const base& that) : x(that.x)
{
cout << "base copy constructorn";
}
此外,如果你有一个现代编译器,你可以编写一个移动构造函数并学习一些新的东西:
base(base&& that) : x(that.x)
{
cout << "base move constructorn";
}
如果v
需要调整其内部缓冲区的大小,它通常会分配一个全新的内存区域,因此它需要将以前在向量中的所有对象复制到新位置。这是使用常规复制完成的,因此会调用复制构造函数。
如果您可以估计需要多少元素,那么您应该在向量上调用reserve()
来提前预留存储。
请注意,std::vector
的调整大小/增长行为取决于实现,因此您的代码示例将使用不同的标准库实现产生不同的结果。
相关文章:
- 当从函数参数中的临时值调用复制构造函数时
- 为什么调用复制构造函数而不是移动构造函数?
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 编译器调用复制运算符而不是移动运算符
- push_back std::vector,则重复调用复制构造函数
- 为什么调用复制构造函数来构造空unique_ptr向量?
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 我打算调用initializer_list构造函数,如果存在,则事先调用复制构造函数:为什么?
- C++ - 从移动分配运算符调用复制分配
- 构造函数初始值设定项列表未调用复制构造函数
- 为什么在我的代码中调用复制构造函数而不是移动构造函数?
- std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数
- 通过引用传递对象时是否调用复制构造函数?
- 如果函数按值传递并按值返回,将调用复制构造函数多少次
- 为什么要抛出引用调用复制构造函数的异常?
- 为什么即使参数标记为"const",也会调用复制构造函数?
- Clang-Tidy:移动构造函数通过调用复制构造函数来初始化类成员
- 为什么当我添加一个不同的对象(复制构造函数中的参数)时调用复制构造函数?
- 为什么调用复制构造函数,当我只返回对象 c++ 的引用时
- 为什么在下面的代码中调用复制构造函数两次