我花了很多年才试图弄清楚为什么会这样.
struct Element { Element(int number) : number_ID(number) { std::cout << "Element number " << number_ID << " is being constructed\n"; } ~Element() { std::cout << "Element number " << number_ID << " is being destroyed\n"; } int number_ID; }; void createVector() { std::vectorobjArr; objArr.reserve(10); // So it doesn't have to reallocate objArr.emplace_back(1); objArr.emplace_back(2); objArr.emplace_back(3); objArr.emplace_back(4); objArr.erase(objArr.begin()); // When I erase the first element only element 4 has destructor called } int main() { createVector(); system("pause"); }
我明白了:
Element number 1 is being constructed Element number 2 is being constructed Element number 3 is being constructed Element number 4 is being constructed //The following called when doing objArr.erase(objArr.begin()); Element number 4 is being destroyed //The following called after createVector() function exits Element number 2 is being destroyed Element number 3 is being destroyed Element number 4 is being destroyed
元素1的析构函数永远不会被调用?起初我不知道为什么在擦除第一个元素时会调用元素4的析构函数,然后我想当它移动它的成员时可能必须调用析构函数.但文档说,删除一个成员之后的所有成员都会被移位,并且2和3的析构函数没有被调用.我真的很困惑.
编辑:如果这是一个优化步骤,那么文档是错误的,因为:
从向量中移除单个元素(位置)或一系列元素([first,last)).
这有效地减少了容器的大小,删除了被删除的元素数量.
那不是在破坏.
vector
正试图保存性能.
什么erase
所做的是它的副本元件2,3和4下一个元件,覆盖含有1所述元件,以便第一元件现在包含2等,然后它破坏了最后一个元素,其是4的副本.
这有消除第一个元素的效果,但并不像你想象的那样.它会删除第一个元素的内容,但不会删除对象本身.
根据您存储的类型vector
,这将比销毁第一个元素更便宜,只是重建第一个元素存储中的第二个元素的副本.
好吧,如果这是一个优化步骤,那么文档是错误的,因为:
...
那不是在破坏.
文档是正确的,它正在摧毁它们.
您的对象是它们包含的值.您声明您的类是可复制的,因此vector
可以自由复制它们.这意味着两个实例具有相同的值是完全合法的.vector
利用这一点.
如果你使你的类不可复制但是noexcept可移动,那么它将正常工作.但是你的移动构造函数也需要将移动的对象置零,这样两个实例就不会有相同的值.