关于构造vector的工作原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于构造vector的工作原理相关的知识,希望对你有一定的参考价值。

代码如下:
#include <iostream.h>
#include <vector.h>
class HP

public:
HP();
HP(const HP &a);
~HP();
;
HP::HP()
cout<<"gouzao"<<endl;

HP::HP(const HP &a)
cout<<"kaobei"<<endl;

HP::~HP()
cout<<"xigou"<<endl;

int main()

vector<HP> sb;
HP a;
sb.push_back(a);
sb.push_back(a);
while(1);

运行结果为
gouzao
kaobei
kaobei
kaobei
xigou
当注释掉其中一行 sb.push_back(a);后运行结果变为
gouzao
kaobei

多的那两行kaobei和xigou哪出来的

warmwormn的回答没有对症下药。
fantacywall的回答有点问题,他说“vector 实际上是链表实现”,实际上vector是用数组实现的,支持随机存取。
下面我给出我的解释:
如上所说,vector是用数组实现的,每次执行push_back操作,相当于底层的数组实现要重新分配大小(即先free掉原存储,后重新malloc);这种实现体现到vector实现就是每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有的vector并释放原有的内存。

例如:
当主函数只有一个push_back时:
int main()

vector<HP> sb;
HP a;
sb.push_back(a);
while(1);

由于原来的vector为空,所以只是分配新的空间,然后拷贝push_back的元素。所以结果如下:
gouzao //这是 语句 HP a; 构造a产生
kaobei //这是 语句 sb.push_back(a) 拷贝新元素产生的。

当主函数有两个push_back时:
int main()

vector<HP> sb;
HP a;
sb.push_back(a);
sb.push_back(a);
while(1);

注意执行第二个push_back时,首先另外分配两个元素的空间,并将原来的vector元素拷过来,后拷贝新push的元素,最后析构原来的元素。故结果如下 :
gouzao //这是 语句 HP a; 构造a产生
kaobei //这是 第一个sb.push_back(a) 拷贝新元素产生的。
kaobei //下面这两个是由第二个sb.push_back(a)产生的,它先先将原来的vector元素拷过来,后拷贝新push的元素
kaobei
xigou //只是析构原来的vector元素产生的。

当主函数有三个push_back时:一样分析,
int main()

vector<HP> sb;
HP a;//构造
sb.push_back(a); //一个拷贝
sb.push_back(a);//两个拷贝,一个析构
sb.push_back(a);//三个拷贝,两个析构
while(1);

结果如下:
gouzao
kaobei
kaobei
kaobei
xigou
kaobei
kaobei
kaobei
xigou
xigou

恕我说的不够周密,希望你能结合我说的仔细思考!
参考技术A 有多少次构造(不管是普通构造还是拷贝构造),就有多少次析构。
多的那次拷贝和析构和vector的实现有关,vector 实际上是链表实现,当需要增加元素时,它的总长度会按一定规则增长,这个规则随C++标准不同而有所变化。但一般来说,它的长度总是比实际的元素个数要大一些。你的例子中两次push_back造成了两次拷贝,但实际上在第二次push_back的时候它为了满足容量需求,根据规则又帮你填进了一个空元素,增加了vector的大小到3。由于你使用的是push_back,那么你当前的一次拷贝已经满足了容量要求,所以之后马上对那个不需要的空元素进行了释放,使得容量又回复到2.这就是为什么多了一次push_back后多出来一次拷贝和析构。
参考技术B class HP

public:
HP();
HP(const HP &a);<-拷贝构造函数
~HP();
;

所以push_back的时候会调用这个构造函数

---
vector是个赋值操作,不是引用
参考技术C ...每次多加一个sb.push_back操作就会多加一次拷贝和析构函数 还是叠加的 参考技术D 实现向量容器的类名是vector(容器是类模板)。包含vector类的头文件名是vector。所以,如果要在程序里使用向量容器,
就要在程序中包含下面语句:
#include <vector>
此外,在定义向量类型对象时,必须指定该对象的类型,因为vector类是一个类模板。
例如,语句:
vector<int> intList;
将intList声明为一个元素类型为int的向量容器对象。类似地,语句:
vector<string> stringList;将stringList声明为一个元素类型为string的向量容器对象。
声明向量对象
vector类包含了多个构造函数,其中包括默认构造函数。
因此,可以通过多种方式来声明和初始化向量容器。

ArrayList与Vector区别

                                            

ArrayList与Vector区别表
ArrayList Vector
1、实现原理:采用动态对象数组实现,默认构造方法创建了一个空数组 1、实现原理:采用动态数组对象实现,默认构造方法创建了一个大小为10的对象数组
2、第一次添加元素,扩展容量为10,之后的扩充算法:原来数组大小+原来数组的一半 2、扩充的算法:当增量为0时,扩充为原来大小的2倍,当增量大于0时,扩充为原来大小+增量
3、不适合进行删除或插入操作 3、不适合进行删除或插入操作
4、为了防止数组动态扩充次数过多,建议创建ArrayList时,给定初始容量。 4、为了防止数组动态扩充次数过多,建议创建Vector时,给定初始容量
5、多线程中使用不安全,适合在单线程访问时使用,效率较高。 5、线程安全,适合在多线程访问时使用,效率较低

以上是关于关于构造vector的工作原理的主要内容,如果未能解决你的问题,请参考以下文章

关于编译原理

关于编译原理

关于JAVA BlockingQueue的工作原理

OpenLayers工作原理

关于TTL电路工作原理,求详细解答

关于 SOLR 及其实际工作原理的一些问题!