这取决于。如果您将输入中的左值传递给您的函数(实际上,如果您传递的东西有一个名称,可以应用地址运算符 & ),那么您的类的复制构造函数将被调用。
void foo(vector<char> v)
{
...
}
int bar()
{
vector<char> myChars = { 'a', 'b', 'c' };
foo(myChars); // myChars gets COPIED
}
如果您要传递一个右值(粗略地说,一些没有名称且不能应用地址运算符 & 的东西)并且该类有一个移动构造函数,那么该对象将被移动(不是,请注意,与创建“别名”相同,而是将对象的内脏转移到新的骨架中,使之前的骨架无用)。
在下面的调用foo()
中, 的结果make_vector()
是一个rvalue。因此,它返回的对象在输入时被移动foo()
(vector
即将调用移动构造函数):
void foo(vector<char> v);
{
...
}
vector<char> make_vector()
{
...
};
int bar()
{
foo(make_vector()); // myChars gets MOVED
}
一些 STL 类具有移动构造函数但没有复制构造函数,因为它们本质上是不可复制的(例如,unique_ptr
)。unique_ptr
当你将它传递给一个函数时,你不会得到它的副本。
即使对于那些确实具有复制构造函数的类,您仍然可以通过使用该std::move
函数将参数从左值更改为右值来强制移动语义,但同样不会创建别名,它只是转移对象的所有权到您正在调用的功能。这意味着您将无法对原始对象执行任何其他操作,除非重新分配给它另一个值或将其销毁。
例如:
void foo(vector<char> v)
{
...
}
vector<char> make_vector()
{
...
};
int bar()
{
vector<char> myChars = { 'a', 'b', 'c' };
foo(move(myChars)); // myChars gets MOVED
cout << myChars.size(); // ERROR! object myChars has been moved
myChars = make_vector(); // OK, you can assign another vector to myChars
}
如果您发现左值和右值引用的整个主题并且移动语义晦涩难懂,那是非常可以理解的。我个人觉得这个教程很有帮助:
http://thbecker.net/articles/rvalue_references/section_01.html
您应该也可以在http://www.isocpp.org或 YouTube 上找到一些信息(查找 Scott Meyers 的研讨会)。