8

我想确保我正确理解这一点。我在这里问它,因为我没有明确说明它的资金。

例如,我有一个基本上是这样构建的三角形网格类:

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;   
}

由于网格中的数据可能会变得非常大,我想实现正确的移动语义。对于指针类型,我完全理解这一点,但要触发右值构造函数,我需要使用移动,对吧?

例如,右值构造函数将是:

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。但我不想人为地限制类的使用。

4

1 回答 1

19

是的,您必须std::move()像您一样在移动构造函数中使用。但是,您的移动构造函数完全复制了默认构造函数。如果您的班级没有定义任何:

  • 复制构造函数
  • 复制赋值运算符
  • 移动赋值运算符
  • 析构函数

然后将为您生成一个默认的移动构造函数,完全按照您的方式进行操作。您最好省略定义并依赖默认定义。

即使您的类定义了上述某些内容,您也可以要求编译器生成默认的移动构造函数:

class Mesh
{
public:
  Mesh(Mesh &&) = default;
  // the rest as before
};

这样,您不必定义它,即使您稍后添加其他成员,它也可以工作(不会忘记将它们添加到手动移动构造函数中)。


不幸的是,以上都不适用于 Visual Studio 2015 或更早版本,它无法生成默认移动构造函数并且不支持= default移动操作。因此,如果您的目标是 VS <= 2015,您必须手动拼出移动构造函数——就像您所做的那样。

于 2013-10-14T10:09:44.897 回答