仅当删除包含对象的向量时,才调用自定义»析构函数«

时间:2017-05-09 09:43:34

标签: c++ oop stdvector

向对象添加析构函数是一种方便的方法,可以确保它清除它可能分配的任何指针,而不依赖于程序员记得这样做。

然而,当使用动态大小的矢量时,一旦将新对象添加到所述矢量,矢量有时会自动将所有对象移动到新位置(编辑:如果矢量的大小超过分配的数据区域,然后向量将其内容复制到一个新位置),导致所有对象的析构函数被调用,就在所有数据被复制到新位置之后:

...
my_vector.push_back(my_object(...));//destructor of all my_objects before this newly added one may just have been called
...

这通常不是问题,因为所有数据都被复制了,但是如果有问题的对象在其析构函数中删除指针指向的对象或数组,或者以任何其他方式取消分配,则可能会出现问题。一些加载的数据 - 例如,删除openGL纹理,缓冲区或着色器:

...
    ~my_object()
    {
        delete[] myArray;
        delete myPointer;
        glDeleteTexture(myTexture);
        //the pointers and texture location may have been copied to the new location, but the data to which they point have been deleted
    }
...
my_vector.push_back(my_object(...));//destructor of all my_objects before this newly added one may just have been called - myPointer, myArray and myTexture now point to no data
...

现在仍然在向量中的旧对象被复制到新位置,指向没有数据,这将是一个问题。 当然,可以通过添加自定义unassign函数来解决此问题,该函数在应删除整个向量时手动调用:

...
    ~my_object()
    {
    }

    void unassign()
    {
        delete[] myArray;
        delete myPointer;
        glDeleteTexture(myTexture);
        //the pointers and texture location may have been copied to the new location, but the data to which they point have been deleted
    }
...
my_vector.push_back(my_object(...));//destructor of all my_objects before this newly added one may just have been called - nevermind
...
for (my_object& M: my_vector) M.unassign();//if this line is not forgotten everything is now unassigned
...

然而问题是,当我使用这种方法时,经常忘记调用这个取消分配函数,留下指向对象的指针,指向数组和OpenGL纹理的指针,缓冲区和未删除的程序。

因此,我的问题是,是否可以对对象进行编程,以便他们删除指针,纹理或任何类似的数据,当且仅当整个向量被删除时,却不需要程序员记住添加特定的线

1 个答案:

答案 0 :(得分:0)

“可以对对象进行编程,这样当它们删除整个向量时,它们就会删除它们的指针,纹理或任何类似的数据。”

没有。对象不知道它们在向量中,更不用说该向量发生了什么。

它也不相关。只要对象本身被销毁,对象就应该销毁它的成员。这可能听起来很浪费,但是由于移动操作,这可能非常便宜。 std::vector将调用你的移动构造函数来创建一个新对象,当vector知道它将在之后销毁旧对象。你通过窃取旧对象的成员来利用这一点,所以当它被破坏时,它会发现自己没有成员。

显然这只适用于你可以偷窃的会员。你只需要复制一个简单的int