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

C++11的新特性

        C++11是由C++标准委员会指定的语言规范。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140 个新特性,以及对C++03标准中约600个缺陷的修正,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅 功能更强大,而且能提升程序员的开发效率。

列表初始化{ }

C++11扩大了{ }的适用范围,使得{ }可以用于所有内置类型和用户自定义类型。

具体例子:

#include<iostream>
#include <vector>
#define NUM 2
class Base
{
public:Base(int left, int right):_left(left),_right(right){}private:int _left;int _right;
};
int main()
{int array[2] = { 1, 2 };std::vector<int> v = { 1, 2, 3 };Base b = { 1, 2 };return 0;
}

变量类型推导auto

应用场景:变量类型太长或者创建变量不清楚类型时。

具体例子:

#include <iostream>
#include <unordered_map>
int main()
{std::unordered_map<std::string, std::string> hash = { {"apple", "苹果"}};std::unordered_map<std::string, std::string>::iterator it = hash.begin();auto cur = it;return 0;
}

注意事项:

1、auto类型不可做函数形参,auto声明的变量必须由编译器在编译时期推导而得。auto推导的类型都是已经被初始化的。

2、当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

3、用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。

decltype类型推导

应用场景:解决需要根据表达式运行完成之后所得结果的类型推导问题。

具体例子:

#include <iostream>
int Func()
{return -1;
}
int main()
{int a = 10;int b = 20;decltype(a + b) c;decltype(Func()) funcType;std::cout << typeid(funcType).name() << std::endl;//intreturn 0;
}

范围for

C++11中提供的一种遍历容器的方法

具体例子:

#include <iostream>
#include <vector>
#include <list>
int main()
{std::list<int> _list = { 1,2,3 };std::vector<int> _v = { 1,2,3 };for (int e : _list)std::cout << e << std::endl;for (int e : _v)std::cout << e << std::endl;return 0;
}

        可以结合auto来进行类型推导,也可以在类型后加&,表示以引用的方式来依此提取右边容器内的元素。

final与override

final和override在C++的多态中使用。

1、final:修饰虚函数,表示该虚函数不能被重写

2、override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写则编译报错。

具体使用:

class Car
{
public:virtual void Drive() final {}
};
class Benz : public Car
{
public:virtual void Drive() {cout << "Benz-舒适" << endl;}
};class Car
{
public:virtual void Drive(){}
};
class Benz : public Car {
public:virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

默认成员函数控制

默认成员函数控制又包括显示缺省函数删除默认函数。

        在C++中对于空类编译器会生成一些默认的成员函数,比如:构造函数、拷贝构造函数、运算符重载、析构 函数和&和const&的重载、移动构造、移动拷贝构造等函数。如果在类中显式定义了,编译器将不会重新生成默认版本。有时候这样的规则可能被忘记,最常见的是声明了带参数的构造函数,必要时则需要定义不带 参数的版本以实例化无参的对象。而且有时编译器会生成,有时又不生成,容易造成混乱,于是C++11让程序员可以控制是否需要编译器生成。

显示缺省函数

C++11中,可以在函数声明或定义时加上 =default 显式的指示编译器生成该函数的默认版本,用=default 修饰的函数称为显式缺省函数。

具体用法:

class Base
{
public:Base(int left, int right):_left(left), _right(right){}Base() = default;
private:int _left;int _right;
};

删除默认函数

如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且不给定义,这样只要其他 人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对 应函数的默认版本,称 =delete 修饰的函数为删除函数。

具体使用:

class Base
{
public:Base(int left, int right):_left(left), _right(right){}Base() = default;Base(const Base&) = delete;Base& operator=(const Base&) = delete;
private:int _left;int _right;
};

右值引用

为了提高程序运行效率,C++11引入右值引用,顾名思义,右值引用只能引用右值。形似int&&

左值与右值

1、 普通类型的变量,因为有名字,可以取地址,都认为是左值。

2.、const修饰的常量,不可修改,只读类型的,理论应该按照右值对待,但因为其可以取地址(如果只是 const类型常量的定义,编译器不给其开辟空间,如果对该常量取地址时,编译器才为其开辟空间), C++11认为其是左值。

3、如果表达式的运行结果是一个临时变量或者临时对象,认为是右值。

4、 如果表达式运行结果或单个变量是一个引用则认为是左值。

左值引用和右值引用

左值引用只能引用左值,但const左值引用既可以引用左值,也可以引用右值。

右值引用一般只能引用右值,但可以引用move后的左值。

具体例子:

int main()
{int a = 10;int& pa = a;int& pb = 10;//报错,左值引用无法引用右值const int& ppa = a;const int& ppb = 10;int&& pa2 = 10;int&& pb2 = a;//报错,右值引用无法引用左值int&& ppa2 = std::move(a);return 0;
}

引入右值引用的具体原因

本质是为了减少拷贝次数,提高效率。例如一个类中的拷贝构造和操作符重载,传值返回时,必须拷贝构造一个临时对象,再通过返回的临时对象来构造接受结果的对象。

看下面一段代码:

class Base
{
public:Base(int left, int right):_left(left), _right(right){}Base operator+(const Base& b){Base tmp (_left + b._left, _right + b._right);return tmp;}
private:int _left;int _right;
};
int main()
{Base a(1, 2);Base b(3, 4);Base c(a + b);return 0;
}

        在operator+中:tmp在按照值返回时,必须创建一个临时对象,临时对象创建好之后,tmp就被销毁了,最后使用返回的临时对象构造c,c构造好之后,临时对象就被销毁了。仔细观察会发现:tmp和所形成临时对象,以及c,每个对象创建后,都有自己独立的空间,而空间中存放内容也都相同,相当于创建了三个内容完 全相同的对象,对于空间是一种浪费,程序的效率也会降低,而且临时对象确实作用不是很大。

移动语义

        C++11提出了移动语义,将一个对象中的资源转移到另一个对象中。依然是上面的代码,通过移动语义,会将tmp返回时构造的临时对象识别为”将亡值“,C++11认为临时对象为右值,将返回对象的资源直接转移给该临时对象,而再构造c时,又会调用移动语义,直接将返回的临时对象资源转移给对象c。

注意:

1、 移动构造函数的参数不能设置成const类型的右值引用,因为资源无法转移而导致移动语义失效。

2.、在C++11中,编译器会为类默认生成一个移动构造,该移动构造为浅拷贝,因此当类中涉及到资源管理时,用户必须显式定义自己的移动构造。

        当需要用右值引用引用一个左值时,可以通过move函数将左值转化为右值。C++11中std::move()函数位于 头文件中,唯一的功能就是将一个左值强制转化为右值引用,然后实现移动语义。被转化的左值,其生命周期并没有随着左值的转化而改变,即std::move转化的左值变量value不会被销毁,但会变的无效。

完美转发

        完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。所谓完美:函数模板在向其他函数传递自身形参时,如果相应实参是左值,它就应该被转发为左值;如果相 应实参是右值,它就应该被转发为右值。

       万能引用,既可以接收左值,也可以接收右值,但万能引用虽然都能接收,但是统一都退化为左值,所以要通过完美转发来保持实参原有的属性。

具体例子:

#include <iostream>
void Fun(int& x) 
{std::cout << "left_value ref" << std::endl;
}
void Fun(int&& x) 
{std::cout << "right_value ref" << std::endl;
}
template<typename T>
void PerfectForward(T&& t) 
{ Fun(std::forward<T>(t));
}
int main()
{int a = 10;PerfectForward(a);PerfectForward(std::move(a));return 0;
}

移动语义具体例子:

#include <iostream>
class Base
{
public:Base(Base&& b):_left(std::move(b._left)),_right(std::move(b._right)){}Base operator=(Base&& b){_left = b._left;_right = b._right;}
private:int _left;int _right;
};

lambda表达式

本质是一种匿名函数。

应用场景:使用algorithm中的sort时,对自定义类型对象进行排序,需要给出对应的比较规则,往往都是通过仿函数来实现,但每出现一个类别,就要定义一个类,写一个用于比较的仿函数,比较繁琐,而lambda表达式可以很好的解决这个问题。

具体例子:

sort(goods, goods + sizeof(goods) / sizeof(goods[0]), [](const Goods& l, const Goods& r)->bool{return l._price < r._price;});

lambda表达式语法

[capture-list] (parameters) mutable -> return-type { statement }

1、[ ]捕捉列表,编译器根据[ ]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。

包括

父作用域:指包含lambda函数的语句块

[ = ]:对父作用域进行传值捕捉

[ & ]:对父作用域进行传引用捕捉

[ val ]:对val变量进行传值捕捉

[ &val ]:对val变量进行传引用捕捉

[ this ]:对当前this指针进行传值捕捉

2、( )参数列表,和普通函数的参数列表相同,可以不传参数。

3、mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。

4、->return-type,表示该lambda表达式最终返回值的类型,可以省略。

5、{ }函数体,除了可以使用其参数外,还可以使用所有捕获到的变量。

        lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。

注意:. lambda表达式之间不能相互赋值,即使看起来类型相同。

        实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如果定义了一 个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()。

相关文章:

C++11的新特性

C11是由C标准委员会指定的语言规范。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140 个新特性&#xff0c;以及对C03标准中约600个缺陷的修正&#xff0c;C11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全&#xff0c;…...

【C语言__动态内存管理__复习篇6】

目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…...

C语言 | Leetcode C语言题解之第30题串联所有单词的子串

题目&#xff1a; 题解&#xff1a; typedef struct {char key[32];int val;UT_hash_handle hh; } HashItem;int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){ int m wordsSize, n strlen(words[0]), ls strlen(s);int *res (int *)mall…...

大数据dolphinscheduler 本地容器化安装

Minio 容器安装 docker run -p 9000:9000 -p 9090:9090 --name minio -d -e "MINIO_ACCESS_KEYminioadmin" -e "MINIO_SECRET_KEYminioadmin" -v D:\SF\DOCKER\minio\data:/data -v D:\SF\DOCKER\minio\config:/root/.minio minio/minio server /da…...

简单的车牌号识别

目录 处理流程与界面各接口编写时遇到的一些问题上传图片识别结果标签显示中文 处理流程与界面 首先点击“上传图片”按钮&#xff0c;可以选择文件夹中含有汽车车牌的图片&#xff0c;并显示在“图片框”中。 点击“检测车牌”按钮&#xff0c;会先对“图片框”中即含有汽车车…...

openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint

文章目录 openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint261.1 功能描述261.2 语法格式261.3 示例261.3.1 忽略非空约束261.3.2 忽略唯一约束261.3.3 忽略分区表无法匹配到合法分区261.3.4 更新/插入值向目标列类型转换失败 o…...

CSS水波纹效果

效果图&#xff1a; 1.创建一个div <div class"point1" click"handlePoint(1)"></div> 2.设置样式 .point1{width: 1rem;height: 1rem;background: #2ce92f;position: absolute;border-radius: 50%;z-index: 999;cursor: pointer;} 3.设置伪…...

迭代器模式:优雅地遍历数据集合

在软件设计中&#xff0c;迭代器模式是一种常见且有用的设计模式&#xff0c;它允许顺序访问一个聚合对象中的各个元素&#xff0c;而又不暴露该对象的内部表示。这种模式在需要对集合进行遍历操作而又不想暴露集合内部结构的场景下非常有用。 一、迭代器模式的使用条件 访问集…...

c++总结笔记(一)

计算机可以将程序转化为二进制指令&#xff08;即机器码&#xff09;&#xff0c;并由CPU执行&#xff0c;CPU会按照指令的顺序依次执行每个指令。 C语言特点&#xff1a; 简洁高效可移植模块化标准化 C语言的标准 C89(C90)标准C99标准C11标准 导入 使用include导入包含…...

[python][gradio]chatbot控件用法

chatbot模块是Gradio中的一个组件&#xff0c;用于展示聊天机器人的输出&#xff0c;包括用户提交的消息和机器人的回复。它支持一些Markdown语法&#xff0c;包括粗体、斜体、代码和图片等。Chatbot模块的输入不接受用户输入&#xff0c;而是通过函数返回的列表来设置聊天内容…...

Sublime Text下载,安装,安装插件管理器,下载汉化插件

SublimeTest官网 © Sublime Text中文网 下载安装 一路点击安装即可 安装插件管理器 管理器官网安装 - 包控制 (packagecontrol.io) 手动安装将3 位置点击网址下载 再打开SublimeTest 点击 选择第一个Browse Packages..... 将会跳转到文件夹中 进入上一个文件夹 在进入…...

c++ ,stl经常出现的<>尖括号其实就是模板类的实例化

通过比如vector<int> 实际上是调用了类似模板template<T t>class vector{...}实例化了一个使用int的vector类来进行定义&#xff0c;我们可以尝试简单的做一个自己的array类 template<typename T1 ,int d2> class array1 {private:T1 *p;int size;public:ar…...

goproxy 简单介绍 及一键安装脚本

goproxy 官网 https://goproxy.cn/ GoProxy 是一项用于 Go 模块的高性能代理服务&#xff0c;旨在为 Go 开发人员提供更快速、更可靠的模块下载体验。它提供以下主要功能&#xff1a; 全球分布式代理服务器: GoProxy 在全球多个地区部署了代理服务器&#xff0c;例如拉斯维加…...

Day13-Python基础学习之数据分析案例

数据分析案例 data_define.py # 数据定义的类 class Record:def __init__(self, date, order_id, money, province):self.date dateself.order_id order_idself.money moneyself.province province ​def __str__(self):return f"{self.date}, {self.order_id}, {se…...

研究生,该学单片机还是plc。?

PLC门槛相对较低&#xff0c;但是在深入学习和应用时&#xff0c;仍然有很高的技术要求。我这里有一套单片机入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习单片机&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&am…...

【Java】导出Mysql表表结构与注释数据字典

需求&#xff1a; 把mysql中所有表的字段名、数据类型、长度、注释整理成csv&#xff0c;做成数据字典。 import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import ja…...

第07-2章 TCP/IP模型

7.7 TCP/IP模型详解 7.7.1 简介 应用层的PDU>APDU&#xff08;Application PDU&#xff09; 表示层的PDU>PPDU&#xff08;Presentation PDU&#xff09; 会话层的PDU>SPDU&#xff08;Session PDU&#xff09; 7.7.2 TCP/IP协议体系 &#xff08;1&#xff09;TCP…...

【办公类-21-15】 20240410三级育婴师 712道单选题(题目与答案合并word)

作品展示 背景需求&#xff1a; 前文将APP题库里的育婴师题目下载到EXCEL&#xff0c;并进行手动整理 【办公类-21-13】 2024045三级育婴师 721道单选题 UIBOT下载整理-CSDN博客文章浏览阅读451次&#xff0c;点赞10次&#xff0c;收藏3次。【办公类-21-13】 2024045三级育婴…...

Vue3+Vant开发:登录功能

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

Linux程序调试优化(1)——内存占用详解及优化思路

文章目录 1.free查看总体的内存占用2./proc/$PID/status 查看某进程状态 linux开发最重要的两个参数&#xff0c;分别是内存以及CPU使用率&#xff0c;若内存出现严重不足&#xff0c;则在需要使用内存时&#xff0c;可能出现申请不到的情况&#xff0c;导致 OOM&#xff0c;L…...

高效解决Visual Studio Code中文乱码问题

文章目录 问题解决步骤 问题 Visual Studio Code新建一个文件编码方式总是默认GBK&#xff0c;如果我不修改成默认UTF-8&#xff0c;那么每次运行&#xff0c;如果有中文需要输出就会乱码&#xff01; 解决步骤 之后我会持续更新&#xff0c;如果喜欢我的文章&#xff0c;请记…...

springboot接口提高查询速度方法

接口想要提高查询速度&#xff0c;需要减少查询数据库的次数&#xff0c;需要把循环里面的查询提出来一次性查询完毕&#xff0c;然后通过java代码来获取响应的值。如下所示&#xff1a; List<OrderInfoHtVO> orderInfoList orderInfoService.getOrderInfoHtlist(query…...

如何在苹果手机上安装iOS应用的.ipa文件?

哈喽&#xff0c;大家好呀&#xff0c;淼淼又来和大家见面啦&#xff0c;如今移动应用市场不断的发展&#xff0c;许多开发者小伙伴们都选择将他们的应用发布到苹果App Store上&#xff0c;但是&#xff0c;有时候他们可能希望通过直接分享IPA文件来分发他们的App&#xff0c;那…...

IDEA pom.xml显示灰色并被划线

在使用 IDEA 进行开发的过程中&#xff0c;有时候会遇到 pom.xml 显示灰色并被划线的情况&#xff0c;如下图&#xff1a; 这一般是因为该文件被 Maven 忽略导致的&#xff0c;可以进行如下操作恢复&#xff1a; 设置保存后&#xff0c;可以看到 pom.xml 恢复了正常&#xff1a…...

玄子Share-使用 Pycharm 执行 Shell 脚本

玄子Share-使用 Pycharm 执行 Shell 脚本 Why&#xff1f; 为什么我要使用 Pycharm 执行 Shell 脚本呢&#xff0c;我直接使用 Linux 不行吗&#xff1f; 使用 Pycharm 执行 Shell 脚本的好处 我们的宿主机都是 WIndows 平台&#xff0c;若想编译 Shell 脚本&#xff0c;我…...

如何让Nrf connect、EFR connect直接显示特征值数据及其单位

效果如图&#xff1a;app直接显示了我的温度&#xff0c;并且有两位小数&#xff0c;还有温度单位。这是怎么做到的呢&#xff1f; 这次我们仍以TLS8258为例&#xff0c;当然如果是其他蓝牙芯片&#xff0c;配置方式也是大差不差&#xff0c;规则一样的。 #define GATT_CHARA…...

python笔记

Vim 修改文件格式 unix|dos vim fileName :set ff //显示出文件格式类型 :set ffunix //设置成unix格式 :set ffdos //windows文件格式python *和**的区别 将可变关键字打包成不可变的元组 def func(*args): print(args) func(1, 2, 3) # 输出&#xff1a;(1, 2, 3)…...

Java编译期注解处理器AbstractProcessor使用

我们接触的注解主要分为以下两类 运行时注解&#xff1a;通过反射在运行时动态处理注解的逻辑编译时注解&#xff1a;通过注解处理器在编译期动态处理相关逻辑 编译期注解我们常用的有Lombok&#xff0c;在class文件中自动生成get和set方法 解编译期处理流程最关键的一个类就…...

JetBrains相关的IDE有哪些?

JetBrains是一家成立于2002年的捷克软件开发公司&#xff0c;总部位于捷克的布拉格&#xff0c;同时在俄罗斯的圣彼得堡及美国麻州波士顿等地设有办公室。该公司以其高质量的集成开发环境&#xff08;IDE&#xff09;产品而闻名&#xff0c;这些产品被广泛应用于各种编程语言和…...

Git-常规用法-含解决分支版本冲突解决方法

目录 前置条件 已经创建了Gitee账号 创建一个远程仓库 Git的优点 版本控制 Git 下载 Git的使用 检查Git的是否安装成功 git的常用命令 常用流程 Git 分支 分支流程 Git 远程仓库 远程仓库流程 特殊 可能遇到的问题 前置条件 已经创建了Gitee账号 创建一个远程仓…...