具有移动和复制语义的构造函数



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

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

每一个都需要对相同的构造函数逻辑进行一个小的变体,并对类似的代码片段进行令人不快的扩展。如果添加其他向量参数,情况将呈指数级恶化。处理这种情况的最佳做法是什么?谢谢

您可以简单地通过值传递:

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

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

为什么不使用构造函数委托(来自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);
};

最新更新