c++ 中std::vector的拷贝构造过程
文章来自阿里校招的一道面试题目,向vector中push n个对象,问对象的构造函数,拷贝构造函数,析构函数分别调用了几次?
vector中的内存分配策略
vector的底层是用动态数组来存储的,当我们用vector<T> vect
这样的形式声明的时候,数组的长度是0,当我们插入第一个元素的时候,数组的长度会变为1,当插入第二个的时候,数组长度会变为2,当插入第三个元素的时候,数组长度变为4,当插入第三,第四个元素的时候,数组长度不变,当插入第五个的时候,数组长度变为8,由此我们可以看到,数组长度的分配策略:
当数组长度不够容纳新的元素时,数组长度变为原来的两倍。
(可以用vect.capacity())
拷贝构造过程
首先构造一个简单的分析过程
#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;
int num = 0;
class Node{
public:
int a;
Node(int a){
this->a = a;
cout<<this<<" "<<"构造函数 "<<a<<endl;
}
Node(const Node & node){
num++;
this->a = node.a;
cout<<this<<" "<<"拷贝构造函数 "<<a<<endl;
}
~Node(){
cout<<this<<" "<<"析构函数 "<<a<<endl;
}
};
int main(){
// freopen("in.txt", "w", stdout);
vector<Node> vect;
for (int i = 0; i<5; i++){
vect.push_back(Node(i));
}
cout<<num<<endl;
}
为了简单,我只push了5个元素,我们看着运行结果简单分析一下:
0x70fe30 构造函数 0
0x151540 拷贝构造函数 0
0x70fe30 析构函数 0
0x70fe30 构造函数 1
0x151a14 拷贝构造函数 1
0x151a10 拷贝构造函数 0
0x151540 析构函数 0
0x70fe30 析构函数 1
0x70fe30 构造函数 2
0x151548 拷贝构造函数 2
0x151540 拷贝构造函数 0
0x151544 拷贝构造函数 1
0x151a10 析构函数 0
0x151a14 析构函数 1
0x70fe30 析构函数 2
0x70fe30 构造函数 3
0x15154c 拷贝构造函数 3
0x70fe30 析构函数 3
0x70fe30 构造函数 4
0x151a20 拷贝构造函数 4
0x151a10 拷贝构造函数 0
0x151a14 拷贝构造函数 1
0x151a18 拷贝构造函数 2
0x151a1c 拷贝构造函数 3
0x151540 析构函数 0
0x151544 析构函数 1
0x151548 析构函数 2
0x15154c 析构函数 3
0x70fe30 析构函数 4
12
0x151a10 析构函数 0
0x151a14 析构函数 1
0x151a18 析构函数 2
0x151a1c 析构函数 3
0x151a20 析构函数 4
第一次插入的时候,容量为0:
首先构造对象,值为0,数组容量变为1,然后拷贝构造,拷贝构造的是动态数组中的元素。
第二次插入的时候,容量为1:
首先构造对象,值为1,发现数组长度不够,数组扩大为原来的2倍,然后拷贝构造1和原来的0。
第三次插入的时候,容量为2:
首先构造对象,值为2,发现数组长度不够,数组扩大为原来的2倍,然后拷贝构造2和原来的0,1。
第四次插入的时候,容量为4:
首先构造对象,值为3,发现数组可以容纳新元素,直接拷贝构造3到数组
第五次插入的时候,容量为4:
首先构造对象,值为4,发现数组长度不够,所有扩大为原来的2倍,然后拷贝构造4和原来的0,1,2,3。
结论分析
通过上面的分析,不难发现,每当发生构造函数的时候,必有一次拷贝构造伴随,然后放入数组中,多余的拷贝过程发生在数组长度不够的时候,每次扩大数组,都要把之前的元素拷贝一次,而扩大数组的时候,也正是数组插入第2n+12n+1元素的时候,这个时候,我们需要把前面的2n2n个元素拷贝一次。
所以当push n个元素到vector中:
- 构造函数调用次数nn次
- 拷贝构造函数调用次数为
- = 1+2+4+⋯+2⌊log(n−1)⌋+n1+2+4+⋯+2⌊log(n−1)⌋+n
- 析构函数调用次数: n+mn+m次
本文分析了C++中std::vector在push元素时构造函数、拷贝构造函数及析构函数的调用情况,并给出了具体的调用次数公式。通过实例代码详细解释了vector的内存分配策略。

2万+

被折叠的 条评论
为什么被折叠?



