我看到您已经接受了一个答案,但我想扩展答案。
正如 deepmax 所说,如果您按值传递,则可以编写构造函数以利用“移动语义”。这意味着可以将数据从一个变量移动到另一个变量,而不是复制数据。
这样写:
class Name{
public:
Name(std::string var): mem_var(std::move(var)){}
std::string mem_var;
};
这似乎是个好主意,但实际上并不比复制构造函数更有效
class Name{
public:
Name(const std::string &var): mem_var(var){}
std::string mem_var;
};
之所以这样,是因为在一般用例中看起来像这样:
auto main() -> int{
Name name("Sample Text");
}
无论哪种方式都只会制作一个副本(请参阅copy elision),而在另一种情况下
auto main() -> int{
std::string myname = "Hugh Jaynus";
Name name(myname);
}
将以“高效”传递值移动语义的方式制作 2 个副本!
这是一个很好的例子,说明何时应该使用复制构造函数(或传递引用),而不是反对它的例子。
恰恰相反……
如果您编写一个使用移动语义的显式构造函数,无论在何种情况下,您都可以获得有效的解决方案。
以下是您可以如何使用两个构造函数编写名称类定义:
class Name{
public:
Name(const std::string &first_, const std::string &last_)
: first(first_), last(last_){}
Name(std::string &&first_, std::string &&last_) // rvalue reference
: first(std::move(first_)), last(std::move(last_)){}
std::string first, last;
};
那么当你使用类时,应该采取更有效的路径。
如果我们回到我们的示例,我们可以重写它们以使用最好或最有效的构造函数:
int main(){
// pass by reference best here
Name myname("Yolo", "Swaggins");
// move most efficient here
// but never use 'first' and 'last' again or UB!
std::string first = "Hugh", last = "Jaynus";
Name yourname(std::move(first), std::move(last));
}
永远不要想当然地认为一种解决方案优于其他所有解决方案!