我创建了一个类来封装 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 会移动。但是在某些情况下我需要复制。我也可以只保留矢量,因为我知道要保留多少纹理。这两种解决方案的问题是我不知道我可能还有什么其他情况,我希望移动语义能够正常工作。
我阅读了有关此问题的其他其他答案,但使用noexcept
并不能解决问题,正如我所说,如果删除复制构造函数,则将选择移动构造函数。即使我删除noexcept
并从中扔东西。它是否正确?如果没有可用的复制构造函数,编译器是否应该使用不安全的移动构造函数?另外,为什么编译器不选择我提供的安全移动构造函数?
(我使用的是 GCC 4.7)
[编辑]
我做了一个例子:http ://liveworkspace.org/code/4bzSMD $6 并意识到如果我保留默认析构函数,那么将使用移动构造函数,但如果我提供析构函数,则它会复制。这是为什么?