提问人:madu 提问时间:9/11/2018 最后编辑:madu 更新时间:9/11/2018 访问量:49
了解将对象插入向矢量时的构造、复制和销毁
Understanding the construction, copy and destruction when inserting objects to a vector
问:
我正在尝试了解 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。
谁能帮我理解这种行为?
答:
但是,我不明白为什么复制的对象具有 ID=0,而不是 1。
复制构造函数保持未初始化状态,因此在访问该值时未定义程序的行为。ObjId
至于第二部分,我不知道发生了什么,也不知道为什么它与第一部分的插入不同,唯一的例外是ID不同。为什么要复制构造 2 个对象
这是因为动态数组数据结构(即动态数组数据结构)的工作方式。无法调整数组的大小。一旦向量的内部数组太小,就会创建一个更大的数组,将旧元素复制(或移动)到新数组中,并销毁旧数组。std::vector
这意味着向量通常初始化为容量为 1?
一个实验并不能说明向量通常做什么。看来,在第一次推送之后,在这种情况下,您的系统上的容量确实是一个。不能保证在其他情况下(例如 的其他实现)中它会是一个。std::vector
评论
在第一种情况下,您保持 ObjId 未初始化,这意味着您很幸运插入了 0,但基本上也可以看到任何值。
通过键入,您可以定义自己的复制构造函数,这意味着您可以显示每个字段的复制方式,因此您错过了构造函数中的语句。A(const A& other) {...}
ObjId = other.ObjId
第二种情况的发生是因为您的向量正在调整大小,因此它必须将所有元素从旧存储复制到新的、更大的存储中,该存储也适合新元素。
评论
ObjId
评论
A(const A& objToCpy) : Objid(objToCpy.Objid) { cout << "Copying object with id: " << ObjId << endl; }