我目前正在优化我的代码,我有一个关于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);
Run Code Online (Sandbox Code Playgroud)
我创建了一个矢量并尝试了以下内容
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
Run Code Online (Sandbox Code Playgroud)
在#1中,复制构造函数被调用(我知道向量存储的值,因此它复制了一个)在#2中它保存了一个复制构造函数调用只调用#3中的构造函数它调用构造函数并移动构造函数
但我发现,在#2,#3处,向量不为空,每次推回/ emplace/emplace_back都会触发现有项目的复制/销毁.
在#2中,它复制"A"并销毁#3中现有的"A",它与"A"和"B"相同
看起来,只要数组发生变化,矢量就会对所有项目进行调整.是否意味着使用类向量会使事情变得低效?这是使用存储指针的向量的最佳解决方案,以便在求助期间没有副本/析构函数调用,只有指针复制?
谢谢
不是度假村,而是重新分配.通过契约,向量需要连续存储其值,就像普通数组一样.保证连续存储的唯一方法是分配一块内存.一旦你得到它,你就完成了.你不能让它变得更大.你所能做的就是分配一个更大的块并复制一切,然后删除旧的较小的内存块.这就是你所看到的.
向量通常会保留一些额外的空间,以容纳可能添加的新元素(这样每次push_back都不会发生这种复制),但是当向量很小时,最初只会留出一点额外空间未来的增长,这种重新分配仍然经常发生.但随着向量增长,越来越多的额外空间被保留,重新分配的次数也越来越少.
如果您事先知道要使用多少值push_back
(),则可以reserve()
预先使用预先分配额外空间,并最小化重新分配.
如果您知道要向向量添加十个值:
vec.reserve(vec.size()+10);
Run Code Online (Sandbox Code Playgroud)
如果向量已经至少有十个值,它可以接受而无需重新分配,那么这不会做任何事情.否则,向量将重新分配足够的额外空间至少十个附加值.保证接下来的十个push_back不会导致重新分配.