创建/向容器添加对象时如何使用构造函数/析构函数

How constructors / destructors are used when creating / adding objects to a container

本文关键字:何使用 析构函数 构造函数 添加 创建 对象      更新时间:2023-10-16

我正在尝试学习在创建和向容器添加对象时如何使用构造函数/销毁。对于以下示例中的 XClass,实现了一个简单的构造函数、一个复制构造函数、一个移动构造函数和一个析构函数:

std::vector<XClass> v;
v.push_back(XClass(1));
v.push_back(XClass(2));

我使用控制台来跟踪构造函数和析构函数的调用方式,以下是我得到的。消息"带有参数 x"是指构造对象时传入的参数。当它为 1 时,它指的是第一个对象 XClass(1(,同样地指的是 XCLass(2(。使用 0 调用析构函数,因为对象已由移动构造函数初始化。

1.simple constructor called with argument 1.
2.move constructor called with argument 1.
3.destructor called with argument 0.
4.simple constructor called with argument 2.
5.move constructor called with argument 2.
6.copy constructor called with argument 1.
7.destructor called with argument 1.
8.destructor called with argument 0.

我可以理解除 6 和 7 之外的所有行。 第一个对象通过第 1 行到第 3 行创建和添加。第二个对象是使用第 4、5 和 8 行创建和添加的。为什么我们需要复制对象并在第 6 行和第 7 行再次销毁它,特别是考虑到我们将第二个对象添加到后面而不移动第一个对象?

特别是考虑到我们将第二个对象添加到背面而不移动第一个对象?

第一个元素以另一种样式移动到此处。

对于 std::vector::p ush_back,当新size()大于capacity()时,重新分配恰好扩展了存储容量。

矢量的存储是自动处理的,正在扩展和 根据需要签订合同。向量通常比静态占用更多的空间 数组,因为分配了更多内存来处理未来的增长。这 向量不需要每次元素重新分配的方式 已插入,但仅在附加内存耗尽时。合计 可以使用capacity()函数查询分配的内存量。

当它发生时,std::vector 将分配新的内部缓冲区,并将所有现有元素复制到新缓冲区中,然后销毁它们并释放旧的内部缓冲区。这就是为什么你会看到一个副本的构造和破坏。

您可以通过 std::vector::reserve 来预留存储容量以避免重新分配,例如

std::vector<XClass> v;
v.reserve(2);
v.push_back(XClass(1));
v.push_back(XClass(2));

然后,您将不会看到其他副本构造和销毁。