C++日新月异的未来代码:C++11(上)

06-02 1609阅读

文章目录

  • 1.统一的列表初始化
    • 1.1 普通{ }初始化
    • 1.2 initializer_list
    • 2.声明
      • 2.1 auto、nullptr
      • 2.2 decltype
      • 3.左值右值
        • 3.1 概念
        • 3.2 左值引用与右值引用比较
        • 3.3 左值引用与右值引用的应用
        • 3.4 完美转发
        • 希望读者们多多三连支持
        • 小编会继续更新
        • 你们的鼓励就是我前进的动力!

          C++11 能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习

          1.统一的列表初始化

          1.1 普通{ }初始化

          struct Point
          {
          	int _x;
          	int _y;
          };
          int main()
          {
          	int array1[] = { 1, 2, 3, 4, 5 };
          	int array2[5] = { 0 };
          	Point p = { 1, 2 };
          	return 0;
          }
          

          在 C++98 中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定

          struct Point
          {
          	int _x;
          	int _y;
          };
          int main()
          {
          	int x1 = 1;
          	int x2{ 2 };
          	int array1[]{ 1, 2, 3, 4, 5 };
          	int array2[5]{ 0 };
          	Point p{ 1, 2 };
          	// C++11中列表初始化也可以适用于new表达式中
          	int* pa = new int[4] { 0 };
          	return 0;
          }
          

          C++11 扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号 =,也可不添加

          简单来说,C++11 一切皆可用 {} 初始化,并且可以不写 =,建议日常定义,不要去掉 =,但是我们要能看懂

          🔥值得注意的是: 像 Point p1 = { 1, 1 } ,是一种多参数隐式转化,无论哪一种初始化方式都是要调用对应的构造函数的

          1.2 initializer_list

          initializer_list 是 C++11 引入的一个轻量级容器,用于支持统一的初始化语法和参数列表初始化。它允许函数或类接收任意数量的同类型参数,并提供简洁的初始化方式

          vector v1 = { 1,2,3 }; // 调用 vector 的 initializer_list 构造函数
          

          stl 中的容器基本都是支持 initializer_list 初始化的,这初始化的方式和上面的隐式类型不同,具体方式如下:

          C++日新月异的未来代码:C++11(上)

          首先要知道 initializer_list 主要有这三个成员

          1. 创建一个临时数组(存储在栈上),包含元素 {1, 2, 3}
          2. 生成一个 initializer_list 对象,该对象引用临时数组(内部保存数组的起始地址和长度)
          3. initializer_list 引用临时数组(不拥有其内存),vector 会将临时数组的内容复制元素到自己的内存空间(堆上),与临时数组无关
          4. 临时数组被销毁

          🔥值得注意的是: vector 是复制引用数组的元素,而不是直接接收,是因为该临时数组销毁之后,如果 vector 还接收着的话会造成悬空引用

          因此 initializer_list 的存在还是很有必要的:

          在 C++11 之前,若想让函数接收一个类似 {1, 2, 3} 的初始化列表作为参数,需要通过数组或容器(如 vector)传递,不够直观。initializer_list 允许函数直接以初始化列表为参数,使代码更符合直觉

          2.声明

          2.1 auto、nullptr

          该 C++ 增加的特性在前面的文章进行过详细讲解,不过多叙述

          传送门:C++命运石之门代码抉择:C++入门(下)

          2.2 decltype

          // decltype的一些使用使用场景
          template
          void F(T1 t1, T2 t2)
          {
          	decltype(t1 * t2) ret;
          	cout 
          	const int x = 1;
          	double y = 2.2;
          	decltype(x * y) ret; // ret的类型是double
          	decltype(&x) p;      // p的类型是int*
          	cout 
          	// 以下的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;
          }
          
          	double x = 1.1, y = 2.2;
          	// 以下几个都是常见的右值
          	10;
          	x + y;
          	fmin(x, y);
          	// 以下几个都是对右值的右值引用
          	int&& rr1 = 10;
          	double&& rr2 = x + y;
          	double&& rr3 = fmin(x, y);
          	// 这里编译会报错:error C2106: “=”: 左操作数必须为左值
          	10 = 1;
          	x + y = 1;
          	fmin(x, y) = 1;
          	return 0;
          }
          
          	// 左值引用只能引用左值,不能引用右值。
          	int a = 10;
          	int& ra1 = a;   // ra为a的别名
          	//int& ra2 = 10;   // 编译失败,因为10是右值
          	// const左值引用既可引用左值,也可引用右值。
          	const int& ra3 = 10;
          	const int& ra4 = a;
          	return 0;
          }
          
          	// 右值引用只能右值,不能引用左值。
          	int&& r1 = 10;
          	// error C2440: “初始化”: 无法从“int”转换为“int &&”
          	// message : 无法将左值绑定到右值引用
          	int a = 10;
          	int&& r2 = a;
          	// 右值引用可以引用move以后的左值
          	return 0;
          }
          
          	static string a;
          	return a;
          }
          int main()
          {
          	string ret = func();
          	return 0;
          }
          
          			cout 
          			cout 
          	string s1("hello world");
          	string s2(s1);
          	string s3(move(s1));
          	return 0;
          }
           cout  cout  cout  cout 
          	Fun(t);
          }
          int main()
          {
          	PerfectForward(10);           // 右值
          	int a;
          	PerfectForward(a);            // 左值
          	PerfectForward(std::move(a)); // 右值
          	const int b = 8;
          	PerfectForward(b);      // const 左值
          	PerfectForward(std::move(b)); // const 右值
          	return 0;
          }
           cout  cout  cout  cout 
          	Fun(forward
          	PerfectForward(10);           // 右值
          	int a;
          	PerfectForward(a);            // 左值
          	PerfectForward(std::move(a)); // 右值
          	const int b = 8;
          	PerfectForward(b);      // const 左值
          ![请添加图片描述](https://i-blog.csdnimg.cn/direct/5331a7028bb842c8987b625c5cc4c15e.png)
          	PerfectForward(std::move(b)); // const 右值
          	return 0;
          }
          
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码