C++ 11 std::vector push_back 方法多次调用 copy/dest?

标签 c++ vector

我目前正在优化我的代码,我有一个关于 std::vector 的问题

我有一个 MyClass 类,我重写了复制/移动构造函数及其相应的运算符。

MyClass(const std::string& id, int x);
MyClass(const MyClass& other);
MyClass(MyClass&& other);
~MyClass();
MyClass& operator=(const MyClass& other);
MyClass& opratror*(MyClass&& other);

我创建了一个 vector 并尝试了以下操作

std::vector<MyClass> vec;
MyClass a("A", 1);
vec.push_back(a);    //#1
vec.emplace_back("B", 2);    //#2
vec.push_back(MyClass("C", 3));    //#3

在 #1 中,复制构造函数被调用(我知道 vector 按值存储,所以它复制了一个) 在#2中它保存了一个复制构造函数调用只调用构造函数 在 #3 中它调用构造函数并移动构造函数

但我发现,在 vector 不为空的 #2、#3 处,每次推回/emplace/emplace_back 都会触发现有项目的复制/销毁。

在 #2 中,它复制“A”并销毁现有的“A” 在 #3 中,它对“A”和“B”做同样的事情

似乎只要数组发生变化, vector 就会重新计算所有项目。 这是否意味着使用类 vector 会降低效率? 这是使用 vector 存储指针的最佳解决方案,以便在求助期间没有复制/析构函数调用,只有指针复制吗?

谢谢

最佳答案

不是度假村,而是重新分配。根据契约(Contract), vector 需要连续存储其值,就像普通数组一样。保证连续存储的唯一方法是分配一 block 内存。一旦你得到它,你就完成了。你不能让它变大。您所能做的就是分配一个更大的 block 并复制所有内容,然后删除旧的较小的内存块。这就是您所看到的。

vector 通常会保留一些额外的额外空间,以容纳可能添加的新元素(这样这种复制不会在每次 push_back 时发生),但是当 vector 较小时,最初只有一点点额外空间为 future 的增长保留,这种重新分配仍然经常发生。但是随着 vector 大小的增长,越来越多的额外空间被保留,并且重新分配发生的频率越来越低。

如果您事先知道您要向 push_back() 分配多少值,则可以预先使用 reserve() 预先分配额外的空间,并且最小化重新分配。

如果您知道要向 vector 中再添加十个值:

vec.reserve(vec.size()+10);

如果 vector 已经有至少十个以上的值可以接受而无需重新分配,那么这什么都不做。否则, vector 将重新分配足够的额外空间以容纳至少十个附加值。接下来的十次 push_back 保证不会导致重新分配。

关于C++ 11 std::vector push_back 方法多次调用 copy/dest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53927034/

相关文章:

java - 将 vector 打印到 JTextArea 时出现间距错误

c# - 从 C# 调用 C++ 函数并将数据发送回 C#

math - 学习游戏编程(第 2 部分)(数学)

android - Visual Studio 2015 Android 模拟器问题

c++ - 使用单个索引访问子矩阵的有效方法

language-agnostic - 你如何归一化零向量

c++,从文件读取到结构,然后读取到 vector (结构被插入 vector 太多次而不是一次)

java - Vector<> 类的 toArray() 方法

c++ - 在使用 Clang 编译 CRTP Singleton 时,如何解决声称缺少 "explicit instantiation declaration"的问题?

c++ - 将 typedef 作为类的非静态成员访问?