c++[左值+右值](25)

左值

对左值取别名
c++[左值+右值](25)_第1张图片
左值举例

int main()
{
	//左值:可以取地址
	int a = 10;
	const int b = 20;
	int* p = &a;             //a,b,p均是左值
	*p = 100;                 //*p也是左值
	return 0;
}

左值引用举例

int main()
{
	//以下 p、b、c、*p都是左值
	int* P = new int(0);
	int b = 1;
	const int c = 2;
	//以下是对左值的引用(取别名)
	int*& rp = p;
	int& rb = b;
	const int& rc = c;
	int& pvalue = *p;
	
	return 0;
}

右值

c++[左值+右值](25)_第2张图片

int main()
{
	//以下 p、b、c、*p都是左值
	int* P = new int(0);
	int b = 1;
	const int c = 2;
	//以下是对左值的引用(取别名)
	int*& rp = p;
	int& rb = b;
	const int& rc = c;
	int& pvalue = *p;
	
	int x = 1.1, y = 2.2;
	//以下为常见右值:不能取地址
	10;
	x + y;
	fmin(x, y);

	//右值引用
	int&& rr1 = 10;
	int&& rr2 = x + y;
	int&& rr3 = fmin(x, y);
	
//左值引用右值
	//double& r1 = x + y;
	const double& r1 = x + y;
	
//右值引用左值,可以引用move后的左值
	//int&& rr5 = b;
	int&& rr5 = move(b);
	return 0;
}

const T& x 既能接受左值又能接受右值

template<class T>
void Func(const T& x)
{
//x既能接收左值,又能接收右值
}

左值引用只能引用左值,不能引用右值,但是const左值引用既可以引用左值,又可以引用右值
右值引用只能引用右值,不能引用左值,但是可以引用move以后的左值
c++[左值+右值](25)_第3张图片
c++[左值+右值](25)_第4张图片
此处rr1和rr2是左值

引用的价值:减少拷贝

在这里插入图片描述
右值引用(Rvalue reference)是C++11引入的一种特性,它可以解决以下几个问题:

  1. 资源转移:右值引用允许对象的资源(如指针、文件句柄等)被转移到另一个对象,而不是进行深拷贝。这可以提高性能,特别是对于大型对象或容器类对象。通过移动语义,可以避免不必要的资源拷贝,减少内存和时间的开销。

  2. 完美转发:右值引用还允许完美转发(Perfect Forwarding),即将参数以原样传递给另一个函数,而不会丢失其值类别(左值或右值)。这对于泛型编程非常有用,可以保留传递参数的准确类型信息,并将其传递给下一个函数。

  3. 临时对象的优化:右值引用可以优化临时对象的创建和销毁。临时对象是指在表达式中创建的临时对象,例如函数返回值、临时变量等。通过使用右值引用,可以避免不必要的拷贝构造和析构函数的调用,提高性能。

  4. 移动语义:右值引用是实现移动语义的基础。移动语义允许对象的资源被转移,而不是进行深拷贝。这对于容器类对象、动态分配的内存等资源管理非常有用,可以提高性能和效率。

移动赋值||移动拷贝||移动构造

移动赋值(Move Assignment)是C++11引入的一种特性,它允许对象之间的资源转移,而不是进行深拷贝。移动赋值通常用于提高性能,特别是对于大型对象或容器类对象。

移动赋值操作符使用双引号(&&)作为参数,并且通常返回一个引用。它的语法如下:

class MyClass {
public:
    // 移动赋值操作符
    MyClass& operator=(MyClass&& other) {
        // 执行资源转移操作
        // ...
        return *this;
    }
};

移动赋值操作符接受一个右值引用参数(MyClass&& other),表示要转移资源的对象。在函数体内部,你可以执行资源的转移操作,例如将指针或资源所有权从other对象转移到当前对象。最后,返回一个引用以支持链式赋值操作。

移动拷贝(Move Copy)是指在C++11中引入的一种特性,它允许通过移动语义来进行对象的拷贝操作。移动拷贝通常用于避免不必要的对象拷贝,提高性能。

移动拷贝操作符使用双引号(&&)作为参数,并且通常返回一个新的对象。它的语法如下:

class MyClass {
public:
    // 移动拷贝操作符
    MyClass(MyClass&& other) {
        // 执行资源转移操作
        // ...
    }
};

移动拷贝操作符接受一个右值引用参数(MyClass&& other),表示要拷贝的对象。在函数体内部,你可以执行资源的转移操作,例如将指针或资源所有权从other对象转移到新创建的对象。

移动构造(Move Construction)是指使用移动语义来创建新对象的过程。移动构造通常用于避免不必要的对象拷贝,提高性能。

移动构造函数使用双引号(&&)作为参数,并且不需要返回任何值。它的语法如下:

class MyClass {
public:
    // 移动构造函数
    MyClass(MyClass&& other) {
        // 执行资源转移操作
        // ...
    }
};

移动构造函数接受一个右值引用参数(MyClass&& other),表示要创建新对象的源对象。在函数体内部,你可以执行资源的转移操作,例如将指针或资源所有权从other对象转移到新创建的对象。

需要注意的是,移动赋值、移动拷贝和移动构造都是使用右值引用参数(&&)来实现的,这是C++11引入的一种特性,用于表示临时对象或可以被转移资源的对象。

希望这可以帮助你理解移动赋值、移动拷贝和移动构造的概念!如果还有其他问题,请随时提问。

万能引用

          t既可以引用左值也可以引用右值
void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }

void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }
template<typename T>
void PerfectForward(T&& t)
{
	Fun(t);
	//完美转发   保持原属性
	Fun(std::forward<T>(t));
}

传左值就是左值&&会被折叠为&
传右值会变成左值(t为左值)
若一直为万能引用属性会丢失

c++[左值+右值](25)_第5张图片

你可能感兴趣的:(C++,c++,开发语言)