我想确保我正确理解这一点。我在这里问它,因为我没有明确说明它。
例如,我有一个三角形网格类,基本上是这样构建的:
class Mesh
{
public:
struct Face
{
unsigned int a;
unsigned int b;
unsigned int c;
};
//...
private:
std::string file;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texcoord;
std::vector<Face> faces;
}
由于网格中的数据可能会变得非常大,因此我想实现正确的移动语义。对于指针类型,我完全理解这一点,但要触发 rvalue 构造函数,我需要使用 move,对吧?
例如,右值构造函数将是:
Mesh::Mesh(Mesh&& other)
: file(std::move(other.file)),
vertices(std::move(other.vertices)),
normals(std::move(other.normals)),
texcoord(std::move(other.texcoord)),
faces(std::move(other.faces) {}
注意:在有人指出显而易见的事情之前,应用程序在许多地方使用share_ptr。但我不想人为地限制该类的使用。
是的,你必须像你一样在移动构造函数中使用std::move()
。但是,您的移动构造函数完全复制了默认构造函数。如果您的类未定义以下任何一项:
- 复制构造函数
- 复制赋值运算符
- 移动赋值运算符
- 破坏者
然后,将为您生成一个默认的移动构造函数,完全按照您所做的操作。您最好省略定义并依赖默认定义。
即使您的类定义了上述某些内容,您也可以要求编译器生成默认的移动构造函数:
class Mesh
{
public:
Mesh(Mesh &&) = default;
// the rest as before
};
这样,您就不必定义它,即使您以后添加其他成员,它也会起作用(没有忘记将它们添加到手动移动构造函数的风险)。
遗憾的是,以上都不适用于 Visual Studio 2015 或更早版本,它无法生成默认的移动构造函数,并且不支持移动操作的= default
。因此,如果你的目标是 VS <= 2015,你必须像你一样手动拼写移动构造函数。