<<C++11 标准新特性: 右值引用与转移语义>>
原文地址如下
http://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/
对MyString那个例子来说。
我写了三个测试用例。
1. MyString a;
a = MyString("Hello"); //调用转移构造函数
std::vector<MyString> vec;
vec.push_back(MyString("World")); //调用转移赋值函数
这种情况下,本身MyString("World")这个对象就是一个临时对象,因此本身他就是右值。因此只要我们给这个类定义了,转移构造函数和转移赋值函数,那么在有右值出现的时候。就会调用我们的转移构造函数和转移赋值函数了。
2. MyString b;
b = a; //调用拷贝构造函数
vec.push_back(b); //调用拷贝赋值函数
因为a,b都为左值,因此会调用拷贝构造函数和拷贝赋值函数。对MyString这个类来说,就会重新分配资源并进行深
拷贝。
3. MyString c;
c = std::move(a); //调用转移构造函数
vec.push_back(std::move(b)); //调用转移赋值函数
因为所有的命名对象都只能是左值引用,如果已知一个命名对象不再被使用,而想对它调用转移构造函数和转移赋值函数,也就是把一个左值引用当做右值引用来使用,就需要std::move,这个函数以非常简单的方式将左值引用转换成右值引用。
另外,大家如果把这三段程序,放到一个main里面测试的话,在定义vec后,需要写上这句
vec.reserve(4)
因为第一次push_back的时候,vector的capacity是1,第二次push_back的时候,vector的capacity为2,这时,vector应该是要重新分配一块区域,把第一次push_back的对象也拷贝过去,因此会多打印出一些printf信息,会干扰我们的分析过程。因此,只有一上来把他的capacity分的大一点,就不会再重新分配内存并拷贝对象了。
muduo里面对boost::function的传递,基本都是用的std::move,估计function对象里面都有转移构造函数和转移赋值函数。