为什么下面的示例输出 6?
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
static int cnt;
A(int a){}
~A(){cnt++;}
};
int A::cnt = 0;
int main()
{
vector <A> a(4,1);
a.push_back(1);
cout << A::cnt;
//cout << a.size();
}
如果删除push_back,它会输出1。我是否正确理解在初始化和添加元素时,向量在堆上为它们分配内存,单独创建每个元素,将其复制到这个地方并从这个地方删除它?
为什么这么难?为什么它不立即在为自己分配的内存中创建这些元素?
即使我正确地表达了这个想法,我也不明白为什么在第一个例子中结果 = 6,而不是 5
要创建向量,您使用了构造函数
那是你的
相当于
随后对您隐式创建的临时对象的销毁
A(1)
使您第一次调用了析构函数。为您已完成的向量添加新元素
这相当于
销毁该临时对象
A(1)
会再次调用析构函数。当一个对象被添加到向量中时,向量的内存被重新分配,将已经存在的四个对象的内容移动到一个新的位置,之后旧的对象被销毁。那是另外 4 个析构函数调用。
总计 - 6 个析构函数调用。
为什么?这里有两个明显的策略:1)使用提供的初始化器
1
独立创建 4 个目标A
,2)首先创建一个类型为 的自包含临时对象A
,然后将其复制 4 次到一个向量中。谁告诉你第一种方法比第二种更好?标准库的设计者有不同的想法。(或者至少当 C++ 中没有转发参数的方法时,他们被迫考虑它。)显然,使用或多或少“重”的构造,更容易构造一个复杂的对象,然后复制完成的对象对象比一次又一次地从头开始设计对象。
当您将单个元素添加到向量时,没有人强迫您遵循
push_back
创建中间对象的路径。你可以做并且确实直接就地创建了一个新对象。