当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么这个物体不被破坏?》经验,为你挑选了1个好方法。

我花了很多年才试图弄清楚为什么会这样.

  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 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> Nicol Bolas..:

vector 正试图保存性能.

什么erase所做的是它的副本元件2,3和4下一个元件,覆盖含有1所述元件,以便第一元件现在包含2等,然后它破坏了最后一个元素,其是4的副本.

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

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

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

...

那不是在破坏.

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

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

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


@TitoneMaurice:然后你的类***不应该是可复制的!***可复制的类是一个类,其中两个实例可以具有相同的值,并且您可以将值从一个传递给另一个.那不是你想要的.[这是封装OpenGL对象的方式](http://stackoverflow.com/documentation/opengl/7556/encapsulating-opengl-objects-with-c-raii#t=201701260337507343073)
@TitoneMaurice如果您编写(更正)复制和移动赋值运算符/构造函数,这不是问题.参见[三规则](http://stackoverflow.com/a/4172724/3893262)(自C++ 11以来的五个).
推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有