[英]Confusion about construction/destruction in vector after std::vector::clear
#include <iostream>
#include <vector>
class A
{
public:
A() { std::cout << "constructor" << std::endl; }
~A() { std::cout << "destructor" << std::endl; }
};
int main()
{
std::vector<A> myvec;
myvec.push_back(A());
myvec.push_back(A());
myvec.clear();
return 0;
}
输出:
constructor
destructor
constructor
destructor
destructor
destructor
destructor
这里有五个对析构函数的调用。 前两个是由于临时传递给push_back
。 还有其他三个电话,但我预计会有两个额外的电话。
myvec.clear()
将只清除两个内容,因此A
析构函数应该只调用两次(而不是三次)。 为什么有一个额外的时间析构函数被调用?
但是,如果我只将一个元素推送到向量而不是两个,那么输出就像我预期的那样。
对std::vector::clear
的调用在这种情况下并不重要,因为当myvec
超出范围时,它的内容无论如何都会被销毁。
我们考虑一下
class A
{
public:
A() { std::cout << "constructor" << std::endl; }
~A() { std::cout << "destructor" << std::endl; }
A (const A &) { std::cout << "A(A&)\n"; }
};
int main()
{
std::vector<A> myvec;
std::cout << "First\n";
myvec.push_back(A());
std::cout << "Second\n";
myvec.push_back(A());
std::cout << '\n'; // to separate the final destruction
myvec.clear();
}
哪个输出
First
constructor <-- First A _temporary_ object created when pushing_back
A(A&) <-- vector makes a *copy* of the temporary
destructor <-- Temporary A is destroyed
Second
constructor <-- Second A _temporary_ object created when pushing_back
A(A&) <-- Reallocation happens: vector can't copy because it ran out of space
A(A&) <-- Copy of the second temporary
destructor <-- Destroy of the temporary
destructor <-- Destroy of the first element
destructor
destructor
如果你std::vector::reserve
一些空间,你就可以摆脱重新分配所产生的副本
std::vector<A> myvec;
myvec.reserve(8);
这证实了什么
First
constructor
A(A&)
destructor
Second
constructor
A(A&)
destructor
push_back
仍在制作参数的副本:这可以通过使您的类可移动来进一步优化。
A(A&&) noexcept = default;
A& operator=(A&&) noexcept = default;
First
constructor
destructor
Second
constructor
destructor
试试这个稍微修改过的程序版本。 现在有一个复制构造函数和一个可选的reserve
(参见程序中的注释)。 发生的事情会更清楚。
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A() { cout << " constructor" << endl; }
A(const A & a) { cout << " copy constructor" << endl; }
~A() { cout << " destructor" << endl; }
};
int main()
{
vector<A> myvec;
// myvec.reserve(100); // <<< remove comment to see the difference
cout << "pushback 1" << endl;
myvec.push_back(A());
cout << "pushback 2" << endl;
myvec.push_back(A());
cout << "pushback 3" << endl;
myvec.push_back(A());
cout << "clear" << endl;
myvec.clear();
cout << "end clear" << endl;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.