在将对象插入向量时了解构造,复制和销毁
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在将对象插入向量时了解构造,复制和销毁相关的知识,希望对你有一定的参考价值。
我试图了解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。
任何人都可以帮我理解这种行为吗?
在第一种情况下,你保持ObjId未初始化,这意味着你很幸运,插入了0,但基本上也可以看到任何值。
通过输入A(const A& other) {...}
,您可以定义自己的复制构造函数,这意味着您将显示每个字段的复制方式,因此您会错过构造函数中的ObjId = other.ObjId
语句。
第二种情况发生是因为您的向量正在调整大小,因此它必须将所有元素从旧存储复制到新的,更大的存储,这也将适合新元素。
但是,我不明白为什么复制的对象有ID = 0,而不是1。
您的复制构造函数将ObjId
保留为未初始化,因此在访问该值时,程序的行为是不确定的。
至于第二部分,我不知道发生了什么以及为什么它与第一次插入不同,唯一的例外是ID不同。为什么要复制2个对象
这是因为动态数组数据结构 - 这是std::vector
的作用 - 是如何工作的。数组无法调整大小。一旦向量的内部数组太小,就会创建一个更大的数组,将旧元素复制(或移动)到新数组,并销毁旧数组。
这意味着矢量通常初始化为1的容量?
一个实验并没有告诉我们通常会做什么。似乎在第一次推送之后,在这种情况下,系统上的容量确实是一个。无法保证在其他情况下(例如std::vector
的其他实现)。
以上是关于在将对象插入向量时了解构造,复制和销毁的主要内容,如果未能解决你的问题,请参考以下文章