十大必掌握C++11新特性

2023-10-31

  简介
  C++11,之前被称作C++0x,即ISO/IEC 14882:2011,是目前的C++编程语言的正式标准。它取代第二版标准ISO/IEC 14882:2003(第一版ISO/IEC 14882:1998发布于1998年,第二版于2003年发布,分别通称C++98以及C++03,两者差异很小)。新的标准包含了几个核心语言增加的新特性,而且扩展C++标准程序库,并入了大部分的C++ Technical Report 1程序库(数学的特殊函数除外)。最新的消息被公布在 ISO C++ 委员会网站(英文)。
  ISO/IEC JTC1/SC22/WG21 C++ 标准委员会计划在2010年8月之前完成对最终委员会草案的投票,以及于2011年3月召开的标准会议完成国际标准的最终草案。然而,WG21预期ISO将要花费六个月到一年的时间才能正式发布新的C++标准。为了能够如期完成,委员会决定致力于直至2006年为止的提案,忽略新的提案。最终,于2011年8月12日公布,并于2011年9月出版。2012年2月28日的国际标准草案(N3376)是最接近于现行标准的草案,差异仅有编辑上的修正。
  本文主要罗列C++11相比较旧版本有重大改变并且我们今后可能会频繁接触的一些功能。
  1、新增基于范围的for循环
  类似Java中foreach语句,为遍历数组提供了很大方便。

int nArr[5] = {1,2,3,4,5};
for(int &x : nArr)
{
    x *=2;   //数组中每个元素倍乘
}

  2、自动类型推断 auto
  它的作用就是当编译器在一个变量声明的时候,能够根据变量赋的值推断该变量的数据类型。这样就有些逼近Python中定义变量的功能,无需提前声明定义的变量的数据类型。例如:

auto i = 1;    //编译器自动推断i为int类型

  这个功能在各种标准模板库容器中使用,作用更突出。如下:

vector<int> vec(6,10);
vector<int>::iterator iter = vec.iterator();
auto iterAuto = vec.iterator(); //相比较上一句方便很多

  3、匿名函数 Lambda
  如果代码里面存在大量的小函数,而这些函数一般只被一两处调用,那么不妨将它们重构成Lambda表达式,也就是匿名函数。作用就是当你想用一个函数,但是又不想费神去命名一个函数。
  该功能函数实际上在其他面向对象语言中早就存在,例如Java,Python都定义了该功能。C++中Lambda表达式格式如下:

[capture](params)->ret { body};

  ① [capture]指定在可见域范围内lambda表达式代码内可见的参数。例如:
- [a, &b],前文定义的a以值方式被表达式捕获,b则是以引用的方式;
- [this] 以值的方式捕获 this 指针。
- [&] 以引用的方式捕获所有的外部自动变量。
- [=] 以值的方式捕获所有的外部自动变量。
- [] 不捕获外部的任何变量。
【注】:const 类型的 lambda 表达式,该类型的表达式不能改捕获(“capture”)列表中的值。
  ② (params)指定lambda表达式内部变量定义。
  ③ ->ret是返回类型,如果 lambda 代码块中包含了 return 语句,则该 lambda 表达式的返回类型由 return 语句的返回类型确定。如果没有 return 语句,则类似 void f(…) 函数。
  ④ {body}是Lambda表达式主题结构。
  例句:

auto func = [](int i){ return i+4};// 可以体会auto的好处了
cout<< func(10) << endl;           //输出为14

  4、后置返回类型(tailng-return-type)

 template Ret adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;}

  这不是合法的C++,因为lhs和rhs还没定义;解析器解析完函数原型的剩余部分之前,它们还不是有效的标识符。
  为此, C++11引入了一种新的函数声明语法,叫做后置返回类型(trailing-return-type)。

template auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}

  这种语法可以用到更普通的函数声明和定义上:

struct SomeStruct  {
    auto func_name(int x, int y) -> int;
};
auto SomeStruct::func_name(int x, int y) -> int {
    return x + y;
}

  关键字auto的这种用法与在自动类型推导中有所不同。
  5、显示重写(覆盖)override和final
  在C++03中,很容易让你在本想重写基类某个函数的时候却意外地创建了另一个虚函数。例如:

struct Base {
    virtual void some_func(float);
}; 
struct Derived : Base {
    virtual void some_func(int);
};

  本来Derived::some_func函数是想替代Base中那个函数的。但是因它的接口不同,又创建了一个虚函数。这是个常见的问题,特别是当用户想要修改基类的时候。
  C++11引入了新的语法来解决这个问题:

struct Base {
    virtual void some_func(float);
}; 
struct Derived : Base {
    virtual void some_func(int) override; // 病态的,不会重写基类的方法
};

  override 这个特殊的标识符意味编译器将去检查基类中有没有一个具有相同签名的虚函数,如果没有,编译器就会报错!
  C++11还增加了防止基类被继承和防止子类重写函数的能力。这是由特殊的标识符final来完成的,例如:

struct Base1 final { };

struct Derived1 : Base1 { }; // 病态的, 因为类Base1被标记为final了

struct Base2 {
    virtual void f() final;
};

struct Derived2 : Base2 {
    void f(); // 病态的, 因为虚函数Base2::f 被标记为final了.
};

  在这个例子中, virtual void f() final;语句声明了一个虚函数却也阻止了子类重写这个函数。它还有一个作用,就是防止了子类将那个特殊的函数名与新的参数组合在一起。
  需要注意的是,override和final都不是C++语言的关键字。他们是技术上的标识符,只有在它们被用在上面这些特定的上下文在才有特殊意义。用在其它地方他们仍然是有效标识符。
  6、空指针常量 nullptr
  NULL通常在C语言中预处理宏定义为(void*)0或者0,这样0就有int型常量和空指针的双重身份。但是C++03中只允许0宏定义为空指针常量,这就会造成如下的错误:

void foo(int n);
void foo(char* cArr);

  上面声明了两个重载函数,当我调用foo(NULL),编译器将会调用foo(int)函数,而实际上我是想调用foo(char*)函数的。为了避免这个歧义,C++11重新定义了一个新关键字nullptr,充当单独空指针常量。
  7、long long int类型
  C++03中,最大的整数类型是long int。它保证使用的位数至少与int一样。 这导致long int在一些实现是64位的,而在另一些实现上却是32位的。C++11增加了一个新的整数类型long long int来弥补这个缺陷。它保证至少与long int一样大,并且不少于64位。这个类型早在C99就引入到了标准C中, 而且大多数C++编译器都以扩展的形式支持这种类型了。
  8、模板的别名
  在进入这个主题前,先弄清楚“模板”和“类型”的区别。类型,是具体的数据类型,可以直接用来定义变量。 模板,是类型的模板,根据这个模板可以产生具体的类型;模板是不能直接定义变量的;当指定了所有的模板参数后,就产生了一个具体的类型,就可以用来定义变量了。
  在C++03中,只能为类型(包括完全特化的模板,也是一种类型)定义别名,而不能为模板定义别名: 

template <typename First, typename Second, int Third>
class SomeType;
template <typename Second>
typedef SomeType<OtherType, Second, 5> TypedefName; // 在C++03中, 这是非法的.

  C++11增加为模板定义别名的能力,用下面这样的语法:

template <typename First, typename Second, int Third>
class SomeType; 
template <typename Second>
using TypedefName = SomeType<OtherType, Second, 5>;
//这种using语法也可以用来定义类型的别名:  
typedef void (*FunctionType)(double);  // 老式语法
using FunctionType = void (*)(double); // 新式语法

  9、允许sizeof运算符可以再类型数据成员上使用,无需明确对象。

struct p {otherClass member;};
sizeof(p::member);

  10、线程支持
  C++11虽然从语言上提供了支持线程的内存模型,但主要的支持还是来自标准库。
  新的标准库提供了一个线程类(std::thread)来运行一个新线程,它带有一个函数对象参数和一系列可选的传递给函数对象的参数。通过std::thread::join()支持的线程连接操作可以让一个线程直到另一个线程执行完毕才停止。std:thread::native_handle()成员函数提供了对底层本地线程对象的可能且合理的平台相关的操作。
  为支持线程同步,标准库增加了互斥体(std::mutex, std::recursive_mutex等)和条件变量(std::condition_variable 和std::condition_variable_any)。这些都是通过RAII锁和加锁算法就可以简单使用的。
  有时为了高性能或底层工作,要求线程间的通信没有开销巨大的互斥锁。原子操作可以达到这个目的,这可以随意地为一个操作指定最小的内存可见度。显式的内存屏障也可以用于这个目的。
  C++11线程库还包含了futures和promises,用于在线程间传递异步结果。并且提供了std::packaged_task来封装可以产生这种异步结果的函数调用。
  更高级的线程支持,如线程池,已经决定留待在未来的 Technical Report 加入此类支持。更高级的线程支持不会是 C++11 的一部份,但是其最终实现将建立在目前已有的线程支持之上。std::async 提供了一个简便方法来运行线程,并将线程绑定在 std::future上。用户可以选择一个工作是要在多个线程上异步的运行,还是在一个线程上运行并等待其所需要的数据。默认的情况,实现可以根据底层硬件选择前面两个选项的其中之一。另外在较简单的使用场景下,实现也可以利用线程池提供支持。
  11、元组类型
  元组(tuple)由预先确定数量的多种对象组成,元组可以看作是struct数据成员的泛化,在Python中是一个基本数据结构。TR1 tuple类型的C++11版本获益于像可变参数模板这样的C++11语言特性。TR1版本的元组需要一个由实现定义的包含的类型的最大数目,而且需要大量的宏技巧来实现。相比之下,C++11版本的不需要显式的实现定义的最大类型数目。尽管编译器有一个内部的模板实例化的最大递归深度,但C++11版的元组不会把它暴露给用户。
  用可变参数模板,元组类的定义看上去像下面这样:

template <class ...Types> class tuple;
//下面是定义和使用元组的一个例子:
typedef std::tuple <int, double, long &, const char *> test_tuple;
long lengthy = 12;
test_tuple proof (18, 6.5, lengthy, "Ciao!");
lengthy = std::get<0>(proof);  // 把'lengthy' 赋值为18.
std::get<3>(proof) = " Beautiful!";  // 修改元组的第四个元素

  其它新增标准程序库
  正则化表达式库<regex>;字符串类<string>字新增与其他类型互换的方法,如to_string(),stoi(),stol等;STL标准模板库新增unordered_map以及unordered_set,基于hash表的关联容器等等。这些详细使用可自行上网查找,也十分重要的知识点。

  以上内容参考以下文章总结:

http://en.wikipedia.org/wiki/C++11
http://www.cnblogs.com/pzhfei/archive/2013/03/02/CPP_new_feature.html#section_6.3
http://www.cnblogs.com/haippy/archive/2013/05/31/3111560.html


个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢!

转载请注明出处:CSDN 无鞋童鞋。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

十大必掌握C++11新特性 的相关文章

随机推荐

  • tf好朋友之matplotlib的使用——scatter散点图的绘制

    tf好朋友之matplotlib的使用 scatter散点图的绘制 散点图绘制常用函数 plt scatter 应用示例 了解了那么多坐标设置 连续图的绘制 现在要来看看散点图了 散点图绘制常用函数 plt scatter scatter的
  • k8s 3master节点做高可用-无坑版

    master1 192 168 0 122 master2 192 168 0 86 master3 192 168 0 144 node1 192 168 0 204 node2 192 168 0 184 1 修改主机名并加入到主机映射
  • Linux——进程信号详解

    目录 一 进程信号的理解 1 1定义 1 2举例 1 3总结 二 进程信号地使用 2 1信号种类 2 2而操作系统向进程发送信号地方式有四种 2 2 1以键盘的方式向进程发送信号 接下来介绍一个系统调用函数signal 2 2 2 以系统调
  • 将hexo自定义域名升级https

    原文转载自我的博客https benym cn 前言 Tips 有什么问题可以在下方留言板留言哦 留下自己的邮箱 可以保证快速回复 最近在折腾博客 发现github上很多人说个人博客支持https很重要 原本的github io域名本来支持
  • 景联文科技可为多模态语音翻译模型提供数据采集支持

    8月22日Facebook的母公司Meta Platforms发布了一种能够翻译和转录数十种语言的人工智能模型 SeamlessM4T 可以在日常生活中或者商务交流中为用户提供更便捷的翻译和转录服务 相较于传统的文本翻译 这项技术的最大区别
  • 重启计算机一直转圈圈,Win10系统开机一直转圈圈进不了系统解决方法

    电脑越来越普及了 而大家都能熟练的操作电脑 但你知道如何解决Win10一直转圈圈不能进系统吗 不知道了吧 其实系统故障非常简单 大家只需要按照小编下述所说的方法操作就可以了 下面小编就给大家分享这篇Win10系统开机一直转圈圈进不了系统解决
  • deb 中标麒麟_注意:银河麒麟和中标麒麟不是同一个操作系统

    很多网友都想问 在国产操作系统中有两个叫麒麟的系统非常有名 一个是银河麒麟 另一个是中标麒麟 它们是否出自于同一个公司 是同一个操作系统 可以肯定的说 银河麒麟和中标麒麟不是同一个操作系统 这里请注意分辨了 包括和优麒麟也不同同一个操作系统
  • 智商100能看懂,内观,生男生女,集体潜意识及智人2.0

    一 这一轮人类发展趋势从外到内 要内观世界 1 人的身体前面是阴 背后是阳 但人是向前走路的 也就是从阳往阴走的 所以人类发展的趋势是阴 也就是往女性化走 从外到内 要内观世界 从目前人类的文明来说 现在的人类比古代的人类来说 男性越来越向
  • 最新高频Android笔试题分享,最新高频安卓面试题目分享

    前言 伟人曾经说过 书是人类进步的阶梯 书中自有黄金屋 书中自有颜如玉 读书破万卷 下笔如有神 书是唯一不死的东西 书籍是伟大的天才留给人类的遗产 最近有很多朋友在我的公众号上提问 Android开发的经典入门教材和学习路线 Android
  • 基于VLC实现RTSP推流桌面(共享桌面)

    基于VLC实现RTSP推流桌面 共享桌面 一 添加VLC头文件和库文件 二 封装RTSPServer推流类 三 测试代码 不清楚推流大概原理的小伙伴 参考 设置VLC播放器进行RTSP推流桌面 共享桌面 这里以VLC 2 2 6版本为例 因
  • 怎么将pdf文件转换成图片?三种方法

    在实际的工作过程中 PDF是非常常见的文档存储格式 也是很多网站默认的保存格式 对于PDF文件来说 其具备很多其他文件格式没有的优势和特点 例如 在PDF文件中 其排版整齐且固定 浏览直观且方便 为工作的开展提供了诸多便利 另外 为了能够提
  • [计算机网络]简单入门HTTPS : 确保Web网站安全

    前言 今天也是刚好看到HTTPS 感觉HTTPS有许多需要总结的地方 这里也是花点时间给大伙总结下 今天会从下面几个点入手给大伙介绍 HTTPS如何解决现有的HTTP安全问题 和HTTP的区别 HTTPS建立连接的过程 HTTPS的缺点 其
  • android蓝牙BLE(二) —— 通信

    android BLE系列 android蓝牙BLE 一 扫描 android蓝牙BLE 二 通信 android蓝牙BLE 三 广播 一 蓝牙基础协议 想了解蓝牙通信之前 需要先了解蓝牙两个最基本的协议 GAP 和 GATT 1 GAP
  • FreeCAD是什么、如何下载(windows+0.18.4版本)和安装以及中文设置

    目录 一 FreeCAD是什么 二 如何下载FreeCAD 三 FreeCAD安装过程 四 如何设置成中文 一 FreeCAD是什么 我本意是想用Qt连接CAD实现CAD的二次开发 实现在qt界面改变参数同时CAD图纸上的尺寸发生相应变化
  • Linux之Web服务器配置(Apache)

    摘要 Web Service技术 能使得运行在不同机器上的不同应用无须借助附加的 专门的第三方软件或硬件 就可相互交换数据或集成 依据Web Service规范实施的应用之间 无论它们所使用的语言 平台或内部协议是什么 都可以相互交换数据
  • 基于stm32f103c8t6HAL库六路电磁寻迹智能车

    基于stm32f103c8t6HAL库六路电磁寻迹智能车 学习单片机第一次参加相关比赛 下面分享一些关于调车的心得 1 控制舵机 舵机是控制小车转向的器件 而PWM波可以控制舵机 占空比越大 舵机旋转角度越大 接下来我们打开cubemx配置
  • FreeSwitch常用命令

    1 通话相关 先打客户 再转坐席 没有录音 EslMessage elme client sendSyncApiCommand originate sofia gateway huawei 015011275853 bridge user
  • JDBC数据源配置及管理

    JDBC驱动程序 JDBC驱动程序组件为java程序连接不同数据库系统提供服务 它通常由数据库系统方开发提供或由第三方提供 下载对应不同数据库的JDBC 数据库连接信息配置 URL 连接数据库系统资源描述符 DriverClass 数据库系
  • 交付文档注意事项

    最近涉及到项目交付 编写了很多技术文档 但因为没有经验导致多次修改 尤其是客户和我们技术人员的关注点其实是不一样的 就导致我没有抓住重点 导致反复修改 这里总结下我的一些经验 文档与技术协议合同对应 就我所经历的项目 前期的技术要求和最后的
  • 十大必掌握C++11新特性

    简介 C 11 之前被称作C 0x 即ISO IEC 14882 2011 是目前的C 编程语言的正式标准 它取代第二版标准ISO IEC 14882 2003 第一版ISO IEC 14882 1998发布于1998年 第二版于2003年