将对象插入向量时了解构造,复制和销毁

时间:2018-09-11 09:59:50

标签: c++ vector constructor stl copy-constructor

我试图了解STL如何处理对象的插入。 我了解STL会从临时调用构造函数或复制构造。

这是我想要理解的代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class A
{
      public:
      int ObjId;;
      A(int id) : ObjId(id)
      {
            cout << "Constructing object with id: " << ObjId << endl;
      }

      A(const A& objToCpy)
      {
            ObjId = objToCpy.ObjId;
            cout << "Copying object with id: " << ObjId << endl;
       }

      ~A()
      {
            cout << "Destructing object with id: " << ObjId << endl;
      }
};


int main()
{
      std::vector<A> vecOfA;

      vecOfA.push_back(A(1));

      cout << "....................." << endl << endl;

      vecOfA.push_back(A(2));

      return 0;
}

这将提供以下输出:

构造ID为1的对象

复制ID为1的对象

销毁ID为1的对象

.......

构造ID为2的对象

复制ID为2的对象

复制ID为1的对象

销毁ID为1的对象

销毁ID为2的对象

.......

销毁ID为1的对象

销毁ID为2的对象

我可以理解第一次插入。创建一个ID = 1的临时对象,然后将其复制并插入到向量中。然后这个临时文件被破坏。

但是,我不明白为什么复制的对象的ID为0,而不是1。

对于第二部分,我不知道发生了什么以及为什么它与第一个插入不一样,唯一的区别是ID不同。为什么要构造2个对象副本,并且两个对象的ID均为0,而不是2。

有人可以帮助我了解这种行为吗?

1 个答案:

答案 0 :(得分:1)

  

但是,我不明白为什么复制的对象的ID为0,而不是1。

您的副本构造函数将ObjId保留为未初始化状态,因此访问该值时程序的行为是不确定的。


  

对于第二部分,我不知道发生了什么以及为什么它与第一个插入不一样,唯一的区别是ID不同。为什么要构造2个对象副本

这是因为动态数组数据结构-std::vector是如何工作的。数组无法调整大小。向量的内部数组太小时,将创建一个更大的数组,将旧元素复制(或移动到)新数组,并将旧数组销毁。


  

这意味着向量通常初始化为1的容量吗?

一个实验没有说明通常的作用。看来,在第一次推送之后,在这种情况下,容量确实是系统上的容量。无法保证在其他情况下(例如std::vector的其他实现)也将是一个。