IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 初学者的C++11学习:右值引用和&&的特性 -> 正文阅读

[C++知识库]初学者的C++11学习:右值引用和&&的特性

内容学习自:爱编程的大丙

一、右值

lvalue是loactor value不是left value,rvalue是read value不是right value。

  • 左值是指储存在内存中,有明确储存地址(地址可取)的数据
  • 右值是指可以提供数据值的(地址不可取)数据

便捷区分法:

  • 可取地址->左值
  • 有名有姓->左值
    //左值
	int num = 9;
	//左值引用
	int& a = num;
	//常量左值引用
	const int& c = num;

		//右值引用
	int&& b = 8;
	//常量右值引用
	const int&& d = 8;

二、右值引用

无论声明左值引用还是右值引用都必须初始化,因为引用只是一个别名,并没有对象的内存空间。

在使用右值引用的时候,其实是延长了这个右值的生命周期,而不是将其赋值给另一个左值。不会占用更多的空间。

注意几点:

  • 左值初始化右值引用是不违法的。
  • 右值不能给普通左值引用赋值。
  • 常量左值引用是一个万能引用,他可以接受左值,右值,常量左值和常量右值。
int back()
{
    return 1; 
}

int a = 1;

//第一条 error
int&& b = a;
//第二条 error
int& c = back();
//第三条
const int& d = back();
const int& e = 1;

三、应用

在 C++ 中在进行对象赋值操作的时候,很多情况下会发生对象之间的深拷贝,如果堆内存很大,这个拷贝的代价也就非常大,在某些情况下,如果想要避免对象的深拷贝,就可以使用右值引用进行性能的优化。

class test14
	{
	public:
		test14() : num(new int(1))
		{
			cout << "基础构造" << endl;
		}
		test14(const test14& t) : num(new int(*t.num))
		{
			cout << "拷贝构造" << endl;
		}
		~test14()
		{
			delete num;
		}
		int* num;
	};
	test14 back_1()
	{
		test14 t;
		return t;
	}

void main()
{
    test14 t = back_1();
	cout<<"num = "<<( * t.num )<< endl;
}

在back_1()函数中先是创建了一个对象,并调用了基本构造函数,然后看到在main中进行了一个将亡值的赋值操作,因为存在指针所以进行了一个深拷贝。但是这个对象没有使用,就进行了一个赋值,相当于多调用了额外的空间来处理这件事。如果想要节省这个空间和时间,可以使用右值引用。右值引用具有移动语义,移动语义可以将资源(堆、系统对象等)通过浅拷贝从一个对象转移到另一个对象,这样就能减少不必要的临时对象的创建、拷贝以及销毁,可以大幅提高 C++ 应用程序的性能。

class test14
	{
	public:
		test14() : num(new int(1))
		{
			cout << "基础构造" << endl;
		}
		test14(const test14& t) : num(new int(*t.num))
		{
			cout << "拷贝构造" << endl;
		}
        
        //添加移动构造
        test14(test14&& t) : num(new int(*t.num))
        {
            t.num = nullptr;
            cout<<"移动构造"<<endl;
        }


		~test14()
		{
			delete num;
		}
		int* num;
	};
	test14 back_1()
	{
		test14 t;
		return t;
	}

void main()
{
    test14 t = back_1();
	cout<<"num = "<<( * t.num )<< endl;
}

见移动构造参数为右值引用,在这个过程只进行了浅拷贝,没有动到指针,而是在拷贝后将原指针置nullptr。移动构造中使用了右值引用,会将临时对象中的堆内存地址的所有权转移给对象t,这块内存被成功续命,因此在t对象中还可以继续使用这块内存。

  • ?对于需要动态申请大量资源的类,应该设计移动构造函数,以提高程序效率。需要注意的是,我们一般在提供移动构造函数的同时,也会提供常量左值引用的拷贝构造函数,以保证移动不成还可以使用拷贝构造函数。

四、&&的特性

还没看

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-06 13:38:43  更:2022-02-06 13:39:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:45:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码