Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 包含对象的向量调用';在重新分配时,无论发生什么,都是析构函数?_C++_Vector_Resources_Destructor_Release - Fatal编程技术网

C++ 包含对象的向量调用';在重新分配时,无论发生什么,都是析构函数?

C++ 包含对象的向量调用';在重新分配时,无论发生什么,都是析构函数?,c++,vector,resources,destructor,release,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()

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

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

    }
struct对象
{
对象(int buffer_ID):buffer_ID(buffer_ID){OpenGLCreateBuffer(buffer_ID,somedata);}
~Object(){OpenGLDeleteBuffer(buffer_ID);}
int缓冲区ID;
};
int main()
{
std::向量objArr;
对象推回(1);
objArr.push_back(2);//重新分配向量时调用析构函数
OpenGLDrawBuffer(objArr[0].buffer_ID);//缓冲区已被删除
}
这真的很烦人,我不明白为什么对正在移动的对象调用析构函数。我环顾四周,我很满意你不能阻止调用析构函数。对于移动语义,我认为使用的技巧是从另一个对象复制内容,并将任何指针设置为null,这样当对它们调用析构函数并释放资源时,delete只是在null ptr上调用

我首先尝试创建一个复制构造函数,并尝试将另一个buffer_ID设置为0,但这仅在复制构造函数采用非常量引用时有效,这似乎不正确。另外,将另一个变量设置为null,这样就可以在null上调用delete,或者将null传递给类似于OpenGL delete函数的对象,这似乎有点骇人听闻,不是吗

我知道会有人告诉我无法阻止调用析构函数,那么在对象可能被重新分配到另一个部分的情况下,我应该怎么做?我认为,析构函数是删除此类内容的最佳位置


谢谢。

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

您的类似乎是。它的析构函数似乎要销毁不是在其构造函数中创建的资源

真正的问题是类的基本设计与
std::vector
的工作方式不兼容。当向量必须重新分配其内容时,它将复制或移动现有实例的构造(如果向量的类支持移动语义),然后销毁所有旧的类实例。这就是向量的工作原理。它就是这样设计的。如果您的类不能这样工作,则不能使用
std::vector
。使用std::list也许是一种选择


但更好的选择是修复类。重新设计,使其符合三条规则。完成后,进一步扩展类以添加移动构造函数,并适当支持移动语义。

使对象遵守“三个规则”(或C++11中的“五个规则”)。使用对象指针向量std::vector objArr不是更好吗;向量可以任意增长\收缩,但指针仍然有效。在原始帖子中,“但这仅在复制构造函数采用非常量引用时有效”。也是,。代码OP提到删除他们帖子中的一个指针。是的,对不起,我重新阅读了这个问题,看到了你来自哪里。我仍然不认为这回答了这个问题<代码>可变(或
常量转换
)不是正确的解决方案。需要移动构造函数和正确的所有权语义。请再次阅读我之前的评论。OP不需要
mutable
或任何类型的发布方法。OP需要一个移动构造函数。在析构函数中删除的缓冲区ID是在构造函数中创建的,我只是没有显示它,对不起,我在插图中遗漏了这一点。你说得对,vector可能不适合我。如果我要制作自己的向量类,移动时它可能不会调用析构函数。如果是,那么你的向量就不是C++了。C++的基础是每个类实例的创建必须导致构造函数调用,并且每个类实例的破坏都必须导致析构函数调用。没有例外。C++11引入的移动语义正是您需要的。它们的引入正是为了实现一种高效的移动对象的方法,同时保持C++使用对象的基本方式完好无损。