C++11 新特性总结

类型推导

auto & decltype

  • auto:让编译器在编译器就推导出变量的类型,可以通过=右边的类型推导出变量的类型。
auto a = 10; // 10是int型,可以自动推导出a是int
  • decltype:相对于auto用于推导变量类型,而decltype则用于推导表达式类型,这里只用于编译器分析表达式的类型,表达式实际不会进行运算。
cont int &i = 1;
int a = 2;
decltype(i) b = 2; // b是const int&

        简单总结:auto用于推导变量类型,而decltype则用于推导表达式类型 

auto

  • auto的使用必须马上初始化,否则无法推导出类型
  • auto在一行定义多个变量时,各个变量的推导不能产生二义性,否则编译失败
  • auto不能用作函数参数
  • 在类中auto不能用作非静态成员变量
  • auto不能定义数组,可以定义指针
  • auto无法推导出模板参数

 

 decltype

对于decltype(exp)有

  • exp是表达式,decltype(exp)和exp类型相同
  • exp是函数调用,decltype(exp)和函数返回值类型相同
  • 其它情况,若exp是左值,decltype(exp)是exp类型的左值引用

左值右值 

概念1

左值:可以放到等号左边的东西叫左值。

右值:不可以放到等号左边的东西就叫右值。

概念2

左值:可以取地址并且有名字的东西就是左值。

右值:不能取地址的没有名字的东西就是右值。

int a = b + c; 

        a是左值,a有变量名,也可以取地址,可以放到等号左边, 表达式b+c的返回值是右值,没有名字且不能取地址,&(b+c)不能通过编译,而且也不能放到等号左边。

int a = 4; // a是左值,4作为普通字面量是右值

左值一般有:

  • 函数名和变量名
  • 返回左值引用的函数调用
  • 前置自增自减表达式++i、--i
  • 由赋值表达式或赋值运算符连接的表达式(a=b, a += b等)
  • 解引用表达式*p

 

纯右值

        运算表达式产生的临时变量、不和对象关联的原始字面量、非引用返回的临时变量、lambda表达式等都是纯右值。

  • 除字符串字面值外的字面值
  • 返回非引用类型的函数调用
  • 后置自增自减表达式i++、i--
  • 算术表达式(a+b, a*b, a&&b, a==b等)
  • 取地址表达式等(&a)

将亡值

        将亡值是指C++11新增的和右值引用相关的表达式,通常指将要被移动的对象、T&&函数的返回值、std::move函数的返回值、转换为T&&类型转换函数的返回值,将亡值可以理解为即将要销毁的值,通过“盗取”其它变量内存空间方式获取的值,在确保其它变量不再被使用或者即将被销毁时,可以避免内存空间的释放和分配,延长变量值的生命周期,常用来完成移动构造或者移动赋值的特殊任务。

 左值引用、右值引用

        左值引用就是对左值进行引用的类型,右值引用就是对右值进行引用的类型,他们都是引用,都是对象的一个别名,并不拥有所绑定对象的堆存,所以都必须立即初始化。

type &name = exp; // 左值引用
type &&name = exp; // 右值引用

 深拷贝、浅拷贝

浅拷贝

  • 对于基本数据类型的成员变量,浅拷贝直接进行值传递,也就是将属性值复制了一份给新的成员变量
  • 对于引用数据类型的成员变量,比如成员变量是数组、某个类的对象等,浅拷贝就是引用的传递,也就是将成员变量的引用(内存地址)复制了一份给新的成员变量,他们指向的是同一个事例。在一个对象修改成员变量的值,会影响到另一个对象中成员变量的值。

深拷贝

  • 对于基本数据类型,深拷贝复制所有基本数据类型的成员变量的值
  • 对于引用数据类型的成员变量,深拷贝申请新的存储空间,并复制该引用对象所引用的对象,也就是将整个对象复制下来。所以在一个对象修改成员变量的值,不会影响到另一个对象成员变量的值。

  注意:

      a和b的data_指针指向了同一块内存,这就是浅拷贝,只是数据的简单赋值,那再析构时data_内存会被释放两次,导致程序出问题。

移动语义 

        拷贝是对于别人的资源,自己重新分配一块内存存储复制过来的资源,而对于移动语义,类似于转让或者资源窃取的意思,对于那块资源,转为自己所拥有,别人不再拥有也不会再使用

        注意:移动语义仅针对于那些实现了移动构造函数的类的对象,对于那种基本类型int、float等没有任何优化作用,还是会拷贝,因为它们实现没有对应的移动构造函数。

        通过std::move()实现,移动语义可以避免很多无用的拷贝,提供程序性能,C++所有的STL都实现了移动语义

完美转发 

        完美转发指可以写一个接受任意实参的函数模板,并转发到其它函数,目标函数会收到与转发函数完全相同的实参,转发函数实参是左值那目标函数实参也是左值,转发函数实参是右值那目标函数实参也是右值。

        通过std::forward()实现。

列表初始化

        直接在变量名后面加上初始化列表来进行对象的初始化。

        使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的

以下几种情况时必须使用初始化列表

1.常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
2.引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
3. 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
 

lambda表达式 

        定义了一个匿名函数,可以捕获一定范围的变量在函数内部使用

auto func = [capture] (params) opt -> ret { func_body; };

        其中func是可以当作lambda表达式的名字,作为一个函数使用,capture是捕获列表,params是参数表,opt是函数选项(mutable之类), ret是返回值类型,func_body是函数体。

一个完整的lambda表达式:

auto func1 = [](int a) -> int { return a + 1; };
auto func2 = [](int a) { return a + 2; };
cout << func1(1) << " " << func2(2) << endl;

如上代码,很多时候lambda表达式返回值是很明显的,c++11允许省略表达式的返回值定义。

lambda表达式允许捕获一定范围内的变量:

  • []不捕获任何变量
  • [&]引用捕获,捕获外部作用域所有变量,在函数体内当作引用使用
  • [=]值捕获,捕获外部作用域所有变量,在函数内内有个副本使用
  • [=, &a]值捕获外部作用域所有变量,按引用捕获a变量
  • [a]只值捕获a变量,不捕获其它变量
  • [this]捕获当前类中的this指针

lambda表达式示例代码:

int a = 0;
auto f1 = [=](){ return a; }; // 值捕获a
cout << f1() << endl;auto f2 = [=]() { return a++; }; // 修改按值捕获的外部变量,error
auto f3 = [=]() mutable { return a++; };

        代码中的f2是编译不过的,因为我们修改了按值捕获的外部变量,其实lambda表达式就相当于是一个仿函数,仿函数是一个有operator()成员函数的类对象,这个operator()默认是const的,所以不能修改成员变量,而加了mutable,就是去掉const属性。

智能指针 

c++11引入了三种智能指针:

  • std::shared_ptr
  • std::weak_ptr
  • std::unique_ptr

shared_ptr

        shared_ptr使用了引用计数,每一个shared_ptr的拷贝都指向相同的内存,每次拷贝都会触发引用计数+1,每次生命周期结束析构的时候引用计数-1,在最后一个shared_ptr析构的时候,内存才会释放。

  • 不要用一个裸指针初始化多个shared_ptr,会出现double_free导致程序崩溃

  • 通过shared_from_this()返回this指针,不要把this指针作为shared_ptr返回出来,因为this指针本质就是裸指针,通过this返回可能 会导致重复析构,不能把this指针交给智能指针管理。

  • 尽量使用make_shared,少用new。

  • 不要delete get()返回来的裸指针。

  • 不是new出来的空间要自定义删除器。

  • 要避免循环引用,循环引用导致内存永远不会被释放,造成内存泄漏。

weak_ptr 

        weak_ptr是用来监视shared_ptr的生命周期,它不管理shared_ptr内部的指针,它的拷贝的析构都不会影响引用计数,纯粹是作为一个旁观者监视shared_ptr中管理的资源是否存在,可以用来返回this指针和解决循环引用问题。

  • 作用1:返回this指针,上面介绍的shared_from_this()其实就是通过weak_ptr返回的this指针

  • 作用2:解决循环引用问题。

unique_ptr 

        std::unique_ptr是一个独占型的智能指针,它不允许其它智能指针共享其内部指针,也不允许unique_ptr的拷贝和赋值。使用方法和shared_ptr类似,区别是不可以拷贝:

nullptr

         nullptr并非整型类别,甚至也不是指针类型,但是能转换成任意指针类型。nullptr的实际类型是std:nullptr_t。

        NULL本质上是个int型的0,其实不是个指针

final & override 

        final用于修饰一个类,表示禁止该类进一步派生和虚函数的进一步重载,override用于修饰派生类中的成员函数,标明该函数重写了基类函数,如果一个函数声明了override但父类却没有这个虚函数,编译报错,使用override关键字可以避免开发者在重写基类函数时无意产生的错误。

default 

        多数时候用于声明构造函数为默认构造函数,如果类中有了自定义的构造函数,编译器就不会隐式生成默认构造函数

delete 

        std::unique_ptr就是通过delete修饰来禁止对象的拷贝的

explicit 

        explicit专用于修饰构造函数,表示只能显式构造,不可以被隐式转换

const 

        const字面意思为只读,可用于定义变量,表示变量是只读的,不可以更改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务模式:业务服务模式

无论是单体应用还是微服务&#xff0c;构建企业应用的业务逻辑/服务在更多方面上都有相似之处而不是差异。在两种方法中&#xff0c;都包含服务、实体、仓库等类。然而&#xff0c;也会发现一些明显的区别。在本文中&#xff0c;我将试图以概念性的方式强调这些区别&#xff0c…

element 表单验证 深层验证绑定

直接上代码 :prop 和prop 都可以&#xff0c;vue2和vue3或者是element、elementplus都可以用 <template><div class"page page-table"><section class"page-query-form"><breadcrumb :hasLine"false" /></section&g…

火山引擎VeDI最新分享:消费行业的数据飞轮从“四更”开始

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 数据飞轮&#xff0c;正在为消费行业的数字化升级提供一套全新模式。 在刚刚结束的《全链路增长&#xff1a;数据飞轮转动消费新生力》专场活动上&#xff0c;火山引…

MySQL 8.0详细安装配置教程

一. 前言 MySQL是目前最为流行的开源数据库产品&#xff0c;是完全网络化跨平台的关系型数据库系统。它起初是由瑞典MySQLAB公司开发&#xff0c;后来被Oracle公司收购&#xff0c;目前属于Oracle公司。因为开源&#xff0c;所以任何人都能从官网免费下载MySQL软件&#xff0c…

SSIS对SQL Server向Mysql数据转发表数据 (二)

1、在SQL Server数据库创建一个数据库表&#xff1a;users USE [Test1] GO/****** Object: Table [dbo].[users] Script Date: 2023/7/27 16:25:11 ******/ SET ANSI_NULLS ON GOSET QUOTED_IDENTIFIER ON GOCREATE TABLE [dbo].[users]([id] [int] IDENTITY(1,1) NOT NUL…

一些有意思的人工智能发展状况数据

随着大型语言模型&#xff08;LLM&#xff09;的引入&#xff0c;机器学习&#xff08;ML&#xff09;和人工智能&#xff08;AI&#xff09;首次被日常开发人员所使用。这些令人感觉很神奇的应用程序&#xff0c;甚至是拥有数十亿研发支出的&#xff0c;在以前连大型科技公司几…

HttpServletRequest类全解析

HttpServletRequest 是 Java Servlet API 中的接口&#xff0c;它是 ServletRequest 接口的子接口&#xff0c;提供了更多用于访问 HTTP 请求信息的方法。HttpServletRequest 主要用于处理客户端发起的 HTTP 请求&#xff0c;并包含了许多用于获取请求信息的方法。 以下是 Htt…

Docker和K8s区别,使用场景,具体怎么使用以及详细命令

目录 一、Docker 和 Kubernetes 的区别二、Docker 的使用场景三、Kubernetes 的使用场景四、Docker 的具体使用方法五、Kubernetes 的具体使用方法 Docker 和 Kubernetes(简称 K8s) 都是容器技术领域中非常重要的工具&#xff0c;但它们在构建、部署和管理容器化应用程序方面发…

Vue2基础七、refnextTick自定义指令

零、文章目录 Vue2基础七、ref&nextTick&自定义指令 1、ref **作用&#xff1a;**利用 ref 和 $refs 可以用于 获取 dom 元素, 或 组件实例**特点&#xff1a;**查找范围 → 当前组件内 (更精确稳定)&#xff0c;用document.querySelect(‘.box’) 获取的是整个页面…

nacos安装与基础配置

源码 https://github.com/alibaba/nacos https://gitee.com/mirrors/Nacos 编译 git clone https://github.com/alibaba/nacos.git cd nacos/ mvn -Prelease-nacos -Dmaven.test.skiptrue clean install -U ls -al distribution/target/// change the $version to your ac…

【数据结构】实验八:树

实验八 树 一、实验目的与要求 1&#xff09;理解树的定义&#xff1b; 2&#xff09;掌握树的存储方式及基于存储结构的基本操作实现&#xff1b; 二、 实验内容 题目一&#xff1a;采用树的双亲表示法根据输入实现以下树的存储&#xff0c;并实现输入给定结点的双亲结点…

基于罪名法务智能知识图谱(含码源):基于280万罪名预测、20W法务问答与法律资讯问答功能

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

如何构建适合自己的DevOps软件测试改进方案

​目录 DevOps成熟度模型分析 构建适合企业自身性能的测试过程改进框架 资料获取方法 根据2022年的DevOps全球调查报告显示&#xff0c;主流软件企业采用或部分采用DevOps且已获得良好成效的占比已达70%&#xff0c;DevOps俨然成为当下软件开发研究的重要方向。 测试作为软…

如何使用 PHP 删除数据?

当你想要从数据库中删除数据时&#xff0c;PHP可以帮你实现这个功能。以下是一些简单的步骤和代码示例&#xff0c;帮助你从新手的角度用幽默的语气回答如何使用PHP删除数据。 首先&#xff0c;你需要连接到数据库。这可以通过使用PHP中的mysqli_connect函数来实现。以下是连接…

uni-app 微信小程序:启用组件按需注入

uni-app 微信小程序&#xff1a;启用组件按需注入 文章目录 uni-app 微信小程序&#xff1a;启用组件按需注入一、官方文档按需注入注意事项 二、HBuilder X 设置三、效果 一、官方文档 https://developers.weixin.qq.com/miniprogram/dev/framework/ability/lazyload.html 按…

kotlin异常处理try-catch-finally

kotlin异常处理try-catch-finally fun main(args: Array<String>) {try {println("a")} catch (e: Exception) {//异常捕获println("a-catch: $e")} finally {//善后&#xff0c;无论是否异常&#xff0c;都会执行println("a-finally")}t…

内存泄漏是什么?有什么危害

内存泄漏是什么&#xff1f;有什么危害 1. 前言1.内存泄漏是什么&#xff1f;2. 为什么会发生内存泄漏3. 内存泄漏的危害4. 总结 1. 前言 在各种项目开发中&#xff0c;内存泄漏是一个很严重的问题。对资源管理、性能优越、系统稳定性&#xff0c;以及是否安全产生极大印象。本…

CCD光斑图像质量分析仪的作用和工作原理

激光光斑的成型在激光加工中起着至关重要的作用&#xff0c;在实际加工中激光可以被变换成各种形状以满足加工需求&#xff0c;激光光斑的形状大致可以被分为四种&#xff1a;矩形、环形、椭圆形、线形。矩形的激光光斑适用于激光切割、激光焊接&#xff0c;环形的激光光斑适用…

odoo16-python框架-动作

总结 1 模型和视图的 设计之美 view_ids, view_id,view_mode 最终目的都是为了生成views, 也就是视图. 模型是死的,像男人,一成不变 视图像女人,千变万化, 姿态万千 一阴一阳之谓道,设计之美又在这里得到了体现 2 所有的动作都可以通过web界面来配置 可以通过在"设…

【Python入门系列】第十八篇:Python自然语言处理和文本挖掘

文章目录 前言一、Python常用的NLP和文本挖掘库二、Python自然语言处理和文本挖掘1、文本预处理和词频统计2、文本分类3、命名实体识别4、情感分析5、词性标注6、文本相似度计算 总结 前言 Python自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&…