我喜欢新的std::move
,但担心它会降低程序的可维护性。
据我所知,如果我创建move constructor
或move assignment operator=()
,我必须从头开始编写 。这就是问题的开始。
这是一个很小的课程: -
class B{
M shouldBeMove; //if it is copied, it is still correct (but prefer move)
C shouldBeCopy; //can be copied or moved, both are equal and ok
//wow, I don't even have to write this line for operator=():-
// this->shouldBeCopy = that.shouldBeCopy
}
B b1;
B b2=b1;
目前,B b2=b1
将同时复制M
和C
。没关系。
现在我想使用std::move
的力量: -
class B{
M shouldBeMove; //now, the program is refactored that it must be moved
// M now has "M& operator=(M&& that)"
C shouldBeCopy;
B& operator=(B&& that){
this->shouldBeMove=std::move(that.shouldBeMove);
this->shouldBeCopy=that.shouldBeCopy; //<-- a bit tedious (1#)
// ... imagine that there are 10 variables to be copied ...
}
}
B b1;
B b2=std::move(b1);
它仍然可以,但有点乏味。 (1#)
然后将来一个月,我可能想要添加一个新字段,例如C shouldBeCopy2
到B
,我还需要在operator=
中添加一行: -
B& operator=(B&& that){
this->shouldBeMove=std::move(that.shouldBeMove);
this->shouldBeCopy=that.shouldBeCopy;
this->shouldBeCopy2=that.shouldBeCopy2; //<--- new line
}
我认为我是一个可能忘记添加该行的类型。 (2#)
1#。如何使它不繁琐?
2#。如何万无一失?
答案 0 :(得分:1)
您应该遵循rule of zero并让编译器生成构造函数并为您分配运算符。
但是当您需要实现可移动类型时,请确保同时实现移动赋值运算符(T& operator=(T&&)
)和移动构造函数(T(T&&)
)。请遵循五条规则并确保该类具有适当的复制构造函数/移动构造函数/复制赋值运算符/移动赋值运算符/析构函数
#include <iostream>
using namespace std;
class M{
public: int database=0;
M& operator=(M&& other){
this->database=other.database;
other.database=0;
return *this;
}
M(M &&other) {
*this = std::move(other);
}
M (M& m)=default;
M ()=default;
~M() { /* free db */ }
};
class B{ // As rule of zero, you don't need to implement constructors and assignment operators
public: M shouldMove;
};
int main() {
B b;
b.shouldMove.database=5;
B b2=std::move(b);
std::cout<< b.shouldMove.database <<std::endl;
std::cout<< b2.shouldMove.database <<std::endl;
return 0;
}