左值和右值
左值:有地址的值
右值:只能放在等式右边的值
- 常量
- 将亡值
- 算术表达式
int f(){ return 10; } int i = 10; int j = f();
|
函数返回值为左值引用,就可以放在等式左边int& GetValue() { static int value = 10; return value; } int main() { int i = GetValue(); cout << i << endl; GetValue() = 5; cout << GetValue() << endl; }
|
非const引用,只能引用左值void f(int& value); f(10);
|
左值引用和右值引用
const
加左值引用,可以兼容右值,相当于创建了一个临时变量,然后进行左值引用。int tmp = 10;f(tmp);
左值引用仅仅接受左值,右值引用仅仅接受右值。
void MyPrint(int& value) { cout << "左值引用" << endl; } void MyPrint(int&& value) { cout << "右值引用" << endl; } void MyPrint(const int& value) { cout << "兼容左值和右值引用" << endl; } int main() { int a = 10; MyPrint(a); MyPrint(10); }
|
移动语义
移动语义用来传递所有权,仅仅移动对象,而不进行复制
#include<iostream> using namespace std;
class String { public: String(const char* data) { printf("Creat!\n"); m_size = strlen(data); m_data = new char[m_size]; memcpy(m_data, data,m_size); } String(const String& other) { printf("copy\n"); m_size = other.m_size; m_data = new char[m_size]; memcpy(m_data, other.m_data, m_size); } String(String&& other) { printf("move\n"); m_size = other.m_size; m_data = other.m_data; other.m_size = 0; other.m_data = nullptr; } ~String() { printf("String的析构函数\n"); delete m_data; } private: char* m_data; int m_size; };
class ENT { public: ENT(String&& data):m_data(move(data)){ printf("R Printf\n"); } ENT(const String& data):m_data(data){ printf("ENT Printf\n"); } String m_data; };
int main() { String s("abd"); ENT t1(s); ENT t2("abd"); String str = "hello"; String str1(move(str)); cout << str.m_size << endl; }
|