--笔记
0.左值,右值
Every expression is either an lvalue or an rvalue.
左值表示程序中必须有一个特定的名字引用到这个值。
例如:
int i = 5; // i is a lvalue
int const j = i; // j is a lvalue
int a[5]; // a[5] is a lvalue
右值表示程序中没有一个特定的名字引用到这个值。
例如:
int i = 10; // 10 is rvalue
1. 左值引用:
一个变量被声明为T&,就是引用到类型T
例如:
int i;
int & r = i; // r refers to i
2. 右值引用:
3. 常左:
例如:
int const i = 5;
4. 常右:
字符常量
5.为何引入右值引用?
为了解决临时对象造成的性能问题。
如果函数返回一个对象,则该对象为一个临时对象,会被拷贝好几遍,因此会导致性能浪费。
RVO(Return Value Optimization):在拷贝构造的情况下省略多余的拷贝。
6.如何使用?
The move function really does very little work. All move
does is accept either an lvalue or rvalue argument, and return it as an rvalue without triggering a copy construction:
template <class T> typename remove_reference<T>::type&& move(T&& a) { return a; }
7.Move语义?
1 // Move_Semantic.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <string> 7 8 using namespace std; 9 10 class A { 11 public: 12 A():str(""),x(0),y(0) 13 { 14 } 15 16 A(string str,int x, int y) 17 { 18 this->str = str; 19 this->x = x; 20 this->y = y; 21 } 22 23 A(A&& a) 24 :str(a.str),x(a.x),y(a.y) 25 { 26 } 27 28 // general copy construct 29 //A(const A& a) 30 // :str(a.str),x(a.x),y(a.y) 31 //{ 32 //} 33 34 string toStr() 35 { 36 char buf[100]; 37 sprintf(buf, "%s: %d %d",str.c_str(), x, y); 38 39 return buf; 40 } 41 42 private: 43 string str; 44 int x; 45 int y; 46 47 }; 48 49 int main() 50 { 51 A a("hello",10,5); 52 53 //A b(a); 54 //cout << "After copy, str is \"" << a.toStr() << "\"\n"; 55 //cout << "After copy, str is \"" << b.toStr() << "\"\n"; 56 57 A c(a); 58 cout << "After move, str is \"" << a.toStr() << "\"\n"; 59 cout << "After move, str is \"" << c.toStr() << "\"\n"; 60 61 return 0; 62 }