为什么这个物体不被破坏?

时间:2017-01-26 03:23:07

标签: c++ vector destructor

我花了很多年时间试图弄清楚为什么会这样。

  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::vector<Element> objArr;
        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))。

     

这有效地减少了容器大小的元素数量   被删除,被摧毁。

那不是在破坏。

1 个答案:

答案 0 :(得分:14)

vector正试图保存效果。

erase做的是将元素2,3和4复制到一个元素下面,覆盖包含1的元素。所以第一个元素现在包含2,等等。然后它会破坏最后一个元素,这是一个副本4。

它具有擦除第一个元素的效果,但并不像你想象的那样。它会删除第一个元素的内容,但不会删除对象本身。

根据您在vector中存储的类型,这将比销毁第一个元素更便宜,只是为了重建第一个元素存储中的第二个元素的副本。

  

如果这是一个优化步骤,那么文档是错误的,因为:

     

...

     

那不是在破坏。

文档是正确的,它正在摧毁它们。

您的对象是它们包含的值。您声明您的类是可复制的,因此vector可以自由复制它们。这意味着两个实例具有相同的值是完全合法的。 vector利用了这一点。

如果你使你的课程不可复制但是不可移动,那么它将正常工作。但是你的移动构造函数也需要将移动的对象置零,这样就不会有两个实例具有相同的值。