使用move?:
重载set(/*args*/)
是否有意义?
//example:
class Person {
private:
//properties
std::string name;
std::string address;
std::string favmovie;
public:
//set without operator=
void set(const std::string& name, const std::string& address, const std::string& favmovie) {
this->name = name;
this->address = address;
this->favmovie = favmovie;
return;
}
//set without operator=
void set(std::string&& name, std::string&& address, std::string&& favmovie) {
this->name = std::move(name);
this->address = std::move(address);
this->favmovie = std::move(favmovie);
return;
}
Person(const std::string& name, const std::string& address, const std::string& favmovie)
: name(name), address(address), favmovie(favmovie) {
}
Person(std::string&& name, std::string&& address, std::string&& favmovie)
: name(std::move(name)), address(std::move(address)), favmovie(std::move(favmovie)) {
}
};
感觉就像通过一点点编辑进行复制和粘贴,但我正在为每个功能或方法执行此操作,目前为止我已达到一致的目的,使它们具有高性能。但这是一个好习惯吗?
答案 0 :(得分:2)
这是您使用pass-by-value的地方:
void set(std::string name, std::string adress, std::string favmovie)
{
this->name = std::move(name);
this->adress = std::move(adress);
this->favmovie = std::move(favmovie);
}
然后,如果参数是一个rvalue,它将被移动到参数中,然后移入this
- 两次移动,没有副本。而使用const左值参考版本,总会有一个副本。对于左值参数的情况,在两种情况下都有1个副本(在值版本中有1个额外的移动,但移动很便宜,无论如何都可以省略。)
答案 1 :(得分:2)
@ M.M的答案的缺点是每次调用set
时都会重新分配存储空间,而通过引用传递参数将允许简单地复制数据,而无需重新分配容量已足以保存通过参数传入的数据。有关详细信息,请参阅Herb Sutter's CppCon talk。所以我建议
void set(const std::string &name, const std::string &adress, const std::string &favmovie)
{
this->name = name;
this->adress = adress;
this->favmovie = favmovie;
}
构造函数可以使用聪明的按值传递技巧,但除非它真的是低级代码,否则很可能不会有优势,IMO可能不值得。
答案 2 :(得分:0)
如果函数的目的本身不能从移动语义中受益,并且该函数不会受益于对可变参数的引用,则没有理由让一个重载版本将rvalue引用作为参数。
对于这里显示的简单功能,答案显然是否定的。但是想到一个函数将某个地方存储其参数的例子并不难。在这种情况下,拥有一个利用移动语义的重载版本,而不是为了存储它而复制构造对象,将会有明显的好处。
这一切都归结为函数需要其参数。