std :: vector在重新分配时调用包含对象的析构函数,不管是什么?

时间:2017-01-26 01:22:41

标签: c++ vector resources destructor release

每当我的对象的向量被重新分配时,对象的析构函数被调用并且它会给我带来问题。

struct Object
    {
        Object(int buffer_ID) : buffer_ID(buffer_ID){ OpenGLCreateBuffer(buffer_ID, somedata);}
        ~Object() { OpenGLDeleteBuffer(buffer_ID); }
        int buffer_ID;
    };

    int main()
    {
        std::vector<Object> objArr;
        objArr.push_back(1);
        objArr.push_back(2);             // Destructor is called when reallocating vector

        OpenGLDrawBuffer(objArr[0].buffer_ID);       // The buffer has been deleted

    }

这真的太烦人了,我不明白为什么在一个被移动的对象上调用析构函数。我环顾四周,我很满意你不能阻止析构函数被调用。使用移动语义我认为使用的技巧是从其他对象复制内容,并将任何指针设置为null,这样当在它们上调用析构函数并释放资源时,就会在nullptr上调用delete。

我首先尝试创建一个复制构造函数,并尝试将另一个buffer_ID设置为0,但这仅在复制构造函数采用非const引用时才有效,这看起来并不正确。此外,将其他变量设置为null以便然后在null上调用delete,或者将null传递给类似于这种情况的类似OpenGL删除函数的行为,似乎hacky,不是吗?

我知道我会被告知我无法阻止析构函数被调用,所以在对象可能被重新分配到另一部分的情况下我该怎么办?析构函数是我认为删除这样的东西的最佳位置。

感谢。

2 个答案:

答案 0 :(得分:4)

您的课程显示在violate the Rule Of Three。它的析构函数似乎会破坏未在其构造函数中创建的资源。

您真正的问题是,您的课程的基本设计与// Use whatever to trigger the modal, in this case a class // Get the modal trigger var modalTriggerObj = $("body").find(".modal-trigger"); modalTriggerObj.on('click', function(e) { e.preventDefault(); // Opens the modal $("#modal").modal(); // Light up the modal trigger with css $(this).addClass('modal-on'); // When the modal hides ... $("#modal").on('hide.bs.modal', function() { // Return the trigger to its default state modalTriggerObj.removeClass('modal-on'); }); }); 的工作方式不兼容。当向量必须重新分配其内容时,它将复制构造或移动构造(如果向量的类支持移动语义)现有实例,然后销毁所有旧类实例。这就是矢量的工作原理。这就是它的设计方式。如果您的课程无法正常工作,则无法使用std::vector。使用std::vector可能是一种选择。

但更好的选择是修复你的课程。重新设计,使其符合三法则。在这之后,进一步扩展您的类以添加移动构造函数,并适当支持移动语义。

答案 1 :(得分:-1)

您可以使用mutable来解决复制构造函数中的const问题。 为什么不向传入的类添加一个释放方法来将指针归零。