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

时间:2017-07-13 02:54:33

标签: c++ vector

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

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

我使用console来跟踪构造函数和析构函数的调用方式,下面是我得到的。消息&#34;带参数x&#34;指构造对象时传入的参数。当它是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行再次破坏它,特别是考虑到我们将第二个物体添加到后面而不移动第一个物体?

1 个答案:

答案 0 :(得分:3)

  

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

第一个元素在这里以另一种方式移动。

对于std::vector::push_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));

然后你不会看到额外的副本构造和破坏。