【C++基础】右值引用和move语义总结


前言

本文主要归纳总结C++语法中的右值引用和move语义,方便以后复习。

一、右值引用

1.什么是右值引用

C++11 引入了右值引用,右值引用是一种新类型的引用。右值引用是设计为仅对右值的引用。左值引用是一个&符号,右值引用是&&符号。例如下面case:

int x{
    5 };
int& lref{
    x }; // l-value reference initialized with l-value x
int&& rref{
    5 }; // r-value reference initialized with r-value 5

右值引用只能引用右值,不能引用左值。

右值引用 是否可以绑定 是否可以修改值
可变左值
不可变左值
右值
const 右值引用 是否可以绑定 是否可以修改值
可变左值
不可变左值
右值

右值引用有两个有用的属性。首先,右值引用将初始化对象的生命周期延长到右 值引用的生命周期(当然const 左值引用可以达到这个效果)。其次,非const y右值引用允许右值!

延长声明周期的例子:

#include <iostream>

class Fraction
{
   
private:
	int m_numerator {
    0 };
	int m_denominator {
    1 };

public:
	Fraction(int numerator = 0, int denominator = 1) :
		m_numerator{
    numerator }, m_denominator{
    denominator }
	{
   
	}

	friend std::ostream& operator<<(std::ostream& out, const Fraction& f1)
	{
   
		out << f1.m_numerator << '/' << f1.m_denominator;
		return out;
	}
};

int main()
{
   
	auto&& rref{
    Fraction{
    3, 5 } }; // r-value reference to temporary Fraction

	// f1 of operator<< binds to the temporary, no copies are created.
	std::cout << rref << '\n';

	return 0;
} // rref (and the temporary Fraction) goes out of scope here

作为一个匿名对象,Fraction(3, 5) 通常会在定义它的表达式的末尾离开作用域。但是,由于我们用它初始化右值引用,因此它的声明周期会延长到main函数末尾,我们当然也可以使用该右值引用。

修改右值的例子:

#include <iostream>

int main()
{
   
    
  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用和move语义是C++ 11中重要的特性之一,可以提高程序的效率和性能。引用是一种新的引用类型,其绑定到临时对象或将要销毁的对象上,而不是左对象。move语义则是利用引用,将一个对象的资源所有权从一个对象转移到另一个对象,避免了不必要的内存拷贝,提高了程序的效率。 下面是一个使用引用和move语义的例子: ```c++ #include <iostream> #include <vector> using namespace std; vector<int> getVector() { vector<int> v = {1, 2, 3, 4}; return v; } int main() { vector<int> v1 = getVector(); // 拷贝构造函数 vector<int> v2 = move(v1); // 移动构造函数 cout << "v1 size: " << v1.size() << endl; // 输出 0 cout << "v2 size: " << v2.size() << endl; // 输出 4 return 0; } ``` 在上面的例子中,getVector函数返回一个临时对象vector<int>,该临时对象是一个。在主函数中,我们使用拷贝构造函数将临时对象的拷贝到v1中,然后使用move函数将v1中的移动到v2中。由于move函数使用了引用,将v1中的资源所有权转移到了v2中,避免了不必要的内存拷贝,提高了程序的效率。最后,我们输出v1和v2的大小,可以看到v1的大小为0,v2的大小为4,说明资源已经成功转移。 需要注意的是,使用move语义之后,原对象的会被移动到新对象中,并且原对象的会被置为默认(例如,对于vector而言,原对象的大小为0)。如果需要保留原对象的,则需要在移动之前先进行一次拷贝操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值