我创建了一个类来封装OpenGL纹理中的一些功能,我的要求非常简单,所以我不需要能够控制纹理数据和类型。我的课程如下(简化):
class Texture
{
std::vector<unsigned char> _data;
[...]
public:
Texture(std::vector<unsigned char> data, vec2 size, GLint internal_format, GLenum format, GLenum type);
Texture(const Texture& other)
{
//copies the data and creates a new buffer with OpenGL
}
Texture(Texture&& other) noexcept
{
//moves the data, copies the buffer id and set the old buffer id to 0
}
}
现在我有另一个使用std :: vector管理一些纹理的类,为了使我的大部分内存管理自动化,我意识到我不需要在堆中分配这些纹理,所以矢量类型是std::vector<Texture>
。问题是,当我向矢量添加新纹理时,它正在制作副本而不是移动。我找到了两个解决方案,如果删除了复制构造函数/赋值运算符,std :: vector就会移动。但我需要在某些情况下复制。我也可以保留矢量,因为我知道我将保留多少纹理。这两个解决方案的问题在于我不知道我可能有什么其他情况,我希望移动语义能够正常工作。
我读了关于这个问题的其他other个答案,但使用noexcept
并没有解决问题,正如我所说,如果删除复制构造函数,将选择移动构造函数。即使我删除noexcept
并从中抛出一些东西。它是否正确?如果没有可用的复制构造函数,编译器是否应该使用不安全的移动构造函数?另外,为什么编译器不会选择我提供的安全移动构造函数?
(我正在使用GCC 4.7)
[编辑]
我做了一个例子:http://liveworkspace.org/code/4bzSMD $ 6 并意识到如果我离开默认的析构函数,那么将使用移动构造函数,但是如果我提供了析构函数,那么它就会复制。那是为什么?
答案 0 :(得分:0)
我仍然不知道为什么GCC选择不安全的移动构造函数如果没有提供复制构造函数,但移动问题来自GCC 4.7上的显式析构函数,默认情况下不是noexcept(true),所以当&# 39;副本可用,编译器会认为它更安全(因为复制不会破坏元素。)
此处有更多信息What is the criteria that the compiler uses to decide if a move operation is safe?