为什么将复制构造器称为25次,而插入循环仅迭代10次
Why the copy constructor is called 25 times, while the insertion loop iterates only 10 times?
我想知道为什么在以下C 代码中,复制构造器被称为10次迭代25次?
如果是10,则OK 10/10 = 1
或20/10 = 2
或30/10 = 3
,但是25/10 = 2.5
?.5
在这里是什么意思?
标题:
class Person
{
public:
Person(std::string name, int age);
Person(const Person &person);
const std::string &getName() const;
int getAge() const;
private:
std::string name;
int age;
};
来源:
Person::Person(string name, int age) : name(std::move(name)), age(age)
{}
Person::Person(const Person &person)
{
this->name = person.name;
this->age = person.age;
static int count = 0;
count++;
cout << ">>Copy-Person::Person(Person &person) " << count << endl;
}
const string &Person::getName() const
{
return name;
}
int Person::getAge() const
{
return age;
}
用法:
int main()
{
vector<Person> persons;
for (int i = 0; i < 10; ++i)
{
Person person(to_string(i + 1), i);
persons.push_back(person);
}
cout << "-----------------------------------------------" << endl;
for (Person &person : persons)
{
cout << "name = " << person.getName() << " age = " << person.getAge() << endl;
}
return 0;
}
输出:
>>Copy-Person::Person(Person &person) 1
>>Copy-Person::Person(Person &person) 2
>>Copy-Person::Person(Person &person) 3
>>Copy-Person::Person(Person &person) 4
>>Copy-Person::Person(Person &person) 5
>>Copy-Person::Person(Person &person) 6
>>Copy-Person::Person(Person &person) 7
>>Copy-Person::Person(Person &person) 8
>>Copy-Person::Person(Person &person) 9
>>Copy-Person::Person(Person &person) 10
>>Copy-Person::Person(Person &person) 11
>>Copy-Person::Person(Person &person) 12
>>Copy-Person::Person(Person &person) 13
>>Copy-Person::Person(Person &person) 14
>>Copy-Person::Person(Person &person) 15
>>Copy-Person::Person(Person &person) 16
>>Copy-Person::Person(Person &person) 17
>>Copy-Person::Person(Person &person) 18
>>Copy-Person::Person(Person &person) 19
>>Copy-Person::Person(Person &person) 20
>>Copy-Person::Person(Person &person) 21
>>Copy-Person::Person(Person &person) 22
>>Copy-Person::Person(Person &person) 23
>>Copy-Person::Person(Person &person) 24
>>Copy-Person::Person(Person &person) 25
-----------------------------------------------
name = 1 age = 0
name = 2 age = 1
name = 3 age = 2
name = 4 age = 3
name = 5 age = 4
name = 6 age = 5
name = 7 age = 6
name = 8 age = 7
name = 9 age = 8
name = 10 age = 9
您没有为persons
向量保留任何内存。这意味着,当push_back
期间的persons.size() == persons.capacity()
时,向量将在堆上分配一个新的较大缓冲区并将每个元素复制到其上。这就是为什么您会看到比预期更多的副本。
如果您写...
persons.reserve(10);
...在循环之前,您将看不到任何"额外"副本。
wandbox上的实时示例
请注意,您可以同时使用std::vector::emplace_back
和std::vector::reserve
避免副本Altogheter:
for (int i = 0; i < 10; ++i)
{
persons.emplace_back(to_string(i + 1), i);
}
这只会打印:
名称= 1 age = 0
名称= 2 age = 1
名称= 3 age = 2
名称= 4 age = 3
名称= 5 age = 4
名称= 6 age = 5
名称= 7 age = 6
名称= 8 age = 7
名称= 9 age = 8
名称= 10 age = 9
wandbox上的实时示例
当vector
的新size()
> capacity()
时,重新定位会发生。所有元素将被复制到新的内部存储中,然后将在当前元素的次数中调用复制构造函数。有关增加容量的详细信息取决于实施,似乎您正在使用的实施仅将每个重新分配的容量增加一倍。所以
#iterator current size capacity times of the copy (for reallocatioin + for push_back)
1 0 0 0 + 1
2 1 1 1 + 1
3 2 2 2 + 1
4 3 4 0 + 1
5 4 4 4 + 1
6 5 8 0 + 1
7 6 8 0 + 1
8 7 8 0 + 1
9 8 8 8 + 1
10 9 16 0 + 1
这就是为什么您获得了25次结果。
正如@VittoriorOmeo所解释的那样,您可以使用std :: vector :: refacter避免重新分配。
当std::vector::size()
到达std::vector::capacity()
时,std::vector
将为更多对象腾出空间,分配 new 更大的容量,并且复制以前将对象存储到新的缓冲区中。
此触发了您的Person
类的新复制构造函数(我使用VS2015尝试了您的代码,我收到了35个复制构造函数)。
请注意,如果您使用reserve()
方法在std::vector
中保留足够的空间,则可以完全收到10个复制构造函数:
vector<Person> persons;
// Reserve room in the vector to store 10 persons
persons.reserve(10);
for (int i = 0; i < 10; ++i)
{
Person person(to_string(i + 1), i);
persons.push_back(person);
}
那是因为在这种情况下,您在向量中腾出了足够的空间,因此向量的大小不会超过其容量(因此,无需分配新的较大的缓冲区,并将旧数据复制到此新的缓冲区中)。
这就是说,如果您的Person
类是 MOVE-CONSTRUCTIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB量所,std::vector
Will Move 先前创建的Person
对象而不是复制它们,它的速度更快。p>如果您在Person
类中添加此行:
class Person
{
public:
...
// Synthesize default move constructor
Person(Person&&) = default;
...
};
即使您不调用vector::reserve()
方法。
- 在基于范围的 for 循环期间插入 std::list 的后面
- 在 C++ 中使用 Vector 在动态数组中插入值,循环
- 增强循环缓冲区push_back在前面插入数据
- 在控制台上输出我从文件中读取的整数,将程序插入无限循环
- C++ - 将数据插入到地图循环的地图中
- 插入无限循环运行的单向链表
- 遍历 STL 映射(集/多集)的最佳方法,同时元素可能会在循环期间被删除并重新插入?
- 插入链表和无限循环的末尾
- 在C 插入内部的手动循环运行不正确
- 向量重声明与循环操作中的插入-C++
- 循环a std :: unordered_map,序列始终是i插入元素的序列
- 为什么将复制构造器称为25次,而插入循环仅迭代10次
- 如何在代码中插入循环输入
- 使用循环在链接列表的前面插入一个节点
- 循环时,如何在C 中创建一个自动插入阵列
- 如何在不使用循环的情况下插入向量
- 如何暂停for cicle(循环)以在数组中插入一些值
- 在的内部插入while循环.把这看作一个脑筋急转弯
- 找到插入循环双链表的正确位置
- 巧克力游戏:输入循环,不插入循环或打印游戏统计数据