当前位置: 首页 > ds >正文

C++11新增标准讲解(上)

一,{}(列表初始化)

        一切对象均可用 {} 初始化,例如下面代码,不管是自定义类型或者内置类型都可以使用{}初始化,还能将=省略。

        需要注意的是当我们使用vector<Data>时不能用{}来初始化,可以发现下图使用{}初始化时,只有年份被初始化了,其他都是使用的缺省值。

        如果需要初始化vector<Data>的话就需要使用std::initializer_list来初始化容器

class Data
{
public:Data(int y=1,int m=1,int d=1):_y(y),_m(m),_d(d){ }Data(const Data& data):_y(data._y),_m(data._m),_d(data._d){ }private:int _y;int _m;int _d;
};int main()
{Data d1 = { 2022,3,5 };//自定义类型Data d2{ 2022,3,5 };//自定义类型vector<Data> v1{ 2003,4,5 };//错误vector<Data> v2 = { 2003,4,7 };//错误vector<Data> v3 = { {2003,3,3},{2026,6,6} };//采用用隐式类型转换v3.push_back({2004,5,8});//隐式类型转return 0;
}

        可以看到push_back也可以使用隐式类型转来插入数据

二,左值和右值

        左值:能被取地址,能持久的存在,不是临时的,生命周期不是瞬间的

        右值:不能被取地址,可以认为临时对象就是右值

int main()
{//左值int a = 2;string s1("ded");int* p = new int(0);cout << &s1 << endl;//右值int b = 3;int c = 4;(b + c);//生命周期就在这一行string("hhh");//匿名对象生命周期也只有这一行cout << &(b + c) << endl;//报错,右值不能取地址return 0;
}

三,左值引用与右值引用

//左值引用
int& a1 = a;
string& ss = s1;//右值引用
string&& sss = string("hhh");
int&& bc = (b + c);

 可以看到左值引用使用一个&,而右值引用使用的是&&。

左值引用与右值引用就是给对应的对象取别名,同时右值引用还能延长对象的生命周期,而左值引用如果需要能延长对象生命周期的话就必须加const。

	const int& r1 = (b + c);//如果想用左值引用给右值取别名,需要加上constint&& r2 = move(b);//如果想用右值引用给左值取别名,需要加上move()

move()是仿函数,作用是将目标对象强制转换为右值

需要注意的是变量表达式都是左值属性,也就意味着⼀个右值被右值引用绑定后,右值引用变量变 量表达式的属性是左值,如果需要保持原来的属性就需要用到完美转发。

类型折叠:我们在将右值或者左值当实参传入函数时,会发生类型折叠

传入右值

template<class T>
void func(T&& a)//T->int
{T b = 6;//T->int
}int main()
{int a = 2, b = 4;int&& x = (a + b);func(x);//传入的是右值,原本是int&&,传入函数后会被折叠成intreturn 0;
}

传入左值

template<class T>
void func(T&& a)//T&&->int&
{T b = 6;//T->int&,会报错,因为6是右值
}int main()
{int a = 2, b = 4;int&& x = (a + b);func(a);//传入的是左值,原本是int&,传入函数后会把后面的&&折叠掉return 0;
}

还需要知道的是&与&,&&折叠之后的属性还是左值,&&只有跟&&折叠时属性才是右值

四,移动构造与移动赋值

        有了右值引用之后就出现了移动构造与移动赋值,大大减少了自定义类型传参时的拷贝

        在没有引进之前,我们如果要接收一个函数返回的局部对象时就会先拷贝生成一个临时对象,然后再将临时对象拷贝给接收的对象,这样效率不是很高。

        如果想要提高效率有两个方法,一种是将需要接收函数返回值的对象直接当函数参数,直接在函数内部改变s的值,还有一种是编译器的优化,编译器如果优化非常的好就可能将原本需要两次拷贝的直接优化成一次拷贝。

string addstring()
{string s1;//...return s1;//会拷贝成临时对象
}void addstring1(string& s)//
{//...直接对s进行操作,因为传入的是引用,里面改变了外面也会改变,就达到了减少拷贝}
int main()
{string s = string(s);return 0;
}

        在引进之后,移动构造和移动赋值的第一个参数都是右值引用的类型,他的本质是要“窃取”引用的 右值对象的资源,而不是像拷贝构造和拷贝赋值那样去拷贝资源,从提高效率。

http://www.xdnf.cn/news/12619.html

相关文章:

  • 【递归、搜索与回溯】专题三 穷举vs暴搜vs回溯vs剪枝
  • 【Vue】指令补充+样式绑定+计算属性+侦听器
  • 6.6 打卡
  • 西门子 S7-1200 PLC 海外远程运维技术方案
  • vue3+TS+eslint9配置
  • 《强连通分量》题集
  • 如何在Windows本机安装Python并确保与Python.NET兼容
  • day46python打卡
  • 1.4 编译库:静态库、动态库
  • Java并发包中的管程:Lock和Condition
  • 基于STM32语音识别柔光台灯
  • 基于深度学习的无人机轨迹预测
  • 《ERP原理与应用教程》第3版习题和答案
  • VSCode - VSCode 放大与缩小代码
  • 嵌入式开发之STM32学习笔记day22
  • 深入解析:为什么 Redis 比 MySQL 快
  • 如何轻松、安全地管理密码(新手指南)
  • 创客匠人:如何通过精准定位实现创始人IP打造与知识变现
  • [C语言实战]C语言操作MySQL数据库(八)
  • Ubuntu18.6 学习QT问题记录以及虚拟机安装Ubuntu后的设置
  • 下载和安装Visual Studio(开发ASP.NET MVC应用)
  • 华为仓颉语言初识:并发编程之同步机制(上)
  • TensorFlow安装全攻略:快速搭建AI开发环境
  • 图像识别预处理(配合pytesseract使用)
  • 基于最大相邻夹角的边缘点提取(matlab)
  • 华为大规模——重塑生产力
  • 软信天成:数据驱动型背后的人工智能,基于机器学习的数据管理
  • FPGA定点和浮点数学运算-实例对比
  • opencv2/opencv.hpp里面有哪些常用的函数
  • 从混乱到秩序:探索管理系统如何彻底改变工作流程