首页 > 后端开发 > C++ > 正文

为什么 `push_back` 会在向量中触发多个复制构造函数调用?

Barbara Streisand
发布: 2024-11-01 07:17:02
原创
532 人浏览过

Why Does `push_back` Trigger Multiple Copy Constructor Calls in a Vector?

向量 Push_back 和多次复制构造函数调用的奥秘

使用向量时,人们可能期望 Push_back 操作只需要少量复制构造函数调用。但是,某些情况可能会出现意外行为,例如多次调用。

考虑以下代码片段:

<code class="cpp">class Myint {
    int my_int;
public:
    Myint() : my_int(0) { /* ... */ }
    Myint(const Myint& x) : my_int(x.my_int) { /* ... */ }
};

int main() {
    vector<Myint> myints;
    Myint x;

    myints.push_back(x); // Call 1
    x.set(1);
    myints.push_back(x); // Call 2
}</code>
登录后复制

直观上,我们预计有两个复制构造函数调用:一个用于第一个 push_back第二个是另一个。然而,输出却讲述了一个不同的故事:

Call 1 (default constructor)
Call 2 (copy constructor: my_int = 0)
Call 3 (copy constructor: my_int = 0)
Call 4 (copy constructor: my_int = 1)
登录后复制

为什么需要额外的调用?

内部向量动力学

在内部,向量通常会分配一定量的内存贮存。当分配的空间耗尽时,向量必须重新分配更多内存。此重新分配会触发将现有元素复制到新内存中。

在给定的代码中,第二个push_back需要重新分配。尽管 Myint 的构造函数仅被调用两次,但复制构造函数却被使用了 3 次。这是因为复制构造函数用于将第一个元素移动到新分配的内存中,并使用其原始值 (my_int = 0) 进行初始化,然后再次调用复制构造函数来创建第二个元素,并使用更新后的值进行初始化 ( my_int = 1).

优化性能

为了减少这些不必要的副本,建议:

  • 预留内存:通过增加向量的初始容量,您可以防止重新分配并最大限度地减少复制操作。
  • 使用 Emplace_back:此方法允许您直接就地构造元素,避免复制或移动。

在这种情况下,使用保留来预分配内存可以有效地将复制构造函数调用减少到两次。此外,emplace_back(0) 将完全消除复制,从而实现最佳性能。

以上是为什么 `push_back` 会在向量中触发多个复制构造函数调用?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!