具有移动和复制语义的构造方法

时间:2018-11-05 11:38:47

标签: c++ move

我需要为我的类编写一个构造函数,该构造函数将两个std :: vector作为参数。这些向量必须在私有成员中复制,当我的用户传递临时或右值引用时,我想使用move语义,否则,我要使用复制语义。这是一个常见问题,导致编写一个副本和一个移动构造函数来处理从同一类的对象开始的构造。但就我而言,我是从两个不同的参数(向量)开始构造的,每个参数可以是左值或右值。所以我必须处理四种不同的情况:

MyClass(const std:vector<float> &v1, const std::vector<float> &v2):
  _v1(v1), _v2(v2) {};
MyClass(const std:vector<float> &v1, std::vector<float> &&v2):
  _v1(v1), _v2(std::move(v2)) {};
MyClass(std:vector<float> &&v1, const std::vector<float> &v2):
  _v1(std::move(v1)), _v2(v2) {};
MyClass(std:vector<float> &&v1, std::vector<float> &&v2): 
  _v1(std::move(v1)), _v2(std::move(v2)) {};

每一个都需要对相同的构造函数逻辑进行少量改动,并带有不愉快的相似代码片段。如果添加其他向量参数,事情将成倍恶化。哪种最佳方法可以处理这种情况?谢谢。

2 个答案:

答案 0 :(得分:6)

您可以简单地按值传递:

MyClass(std::vector<float> v1, std::vector<float> v2)
    : _v1(std::move(v1)), _v2(std::move(v2)) {}

这是以每个参数一个额外的移动构造函数调用为代价的(无论参数是左值还是右值),该优化可能被优化也可能未被优化。

答案 1 :(得分:0)

为什么不使用构造函数委托(来自c ++ 11):

MyClass(std::vector<float>&& v1, std::vector<float>&& v2) : 
    _v1(std::move(v1)), _v2(std::move(v2)) {};

MyClass(std::vector<float>&& v1, std::vector<float>&& v2, std::vector<float> &&v3):
    MyClass(v1, v2) {
    _v3 = std::move(v3);
}

这是避免代码重复的好方法。请注意,您不能将构造函数委托与成员初始化混在一起。

如果您还需要一个带有单个向量的构造函数,则可以将上面的代码片段重写为:

MyClass(std::vector<float>&& v1) : 
    _v1(std::move(v1)){};

MyClass(std::vector<float>&& v1, std::vector<float>&& v2) : 
    MyClass(v1) {    //
    _v2 = std::move(v2);
};

MyClass(std::vector<float>&& v1, std::vector<float>&& v2, std::vector<float> &&v3):
    MyClass(v1, v2) {
    _v3 = std::move(v3);
};