C++版本发展史

1. C++ 98

2. C++ 03

3. C++ 11

    3.1 nullptr

    3.2 auto

    3.3 decltype

    3.4 初始化列表

    3.5 范围for循环

    3.6 右值引用

    3.7 字符串字面量

    3.8 noexcept

    3.9 constexpr

    3.10 template特性

    3.11 Lambda表达式

    3.12 函数声明语法

    3.13 强类型枚举

    3.14 新增基础类型

    3.15 多线程Thread

    3.16 智能指针

    3.17 元组std::tuple

    3.18 新增容器

    3.19 构造函数

4. C++ 14

5. C++ 17

6. C++ 20

    6.1 模块 (Modules)

    6.2 协程 (Coroutines)

    6.3 范围 (Ranges)

    6.4 概念与约束 (Constraints and concepts)


     C++是一门以C为基础发展而来的一门面向对象的高级程序设计语言,从1983年由Bjarne Stroustrup教授在贝尔实验室创立开始至今,已有30多个年头。C++从最初的C with class,经历了从C++98、C++ 03、C++ 11、C++ 14、C++17再到C++ 20多次标准化改造,功能得到了极大的丰富,已经演变为一门集面向过程、面向对象、函数式、泛型和元编程等多种编程范式的复杂编程语言。

年份

C++ 标准名称

非正式名称

1998

ISO/IEC 14882:1998

C++98

2003

ISO/IEC 14882:2003

C++03

2011

ISO/IEC 14882:2011

C++11

2014

ISO/IEC 14882:2014

C++14

2017

ISO/IEC 14882:2017

C++17

2020

ISO/IEC 14882:2020

C++20

1. C++ 98

    1954年,John Backus发明了世界上第一种计算机高级语言Fortran,为之后出现的高级编程语言奠定了基础。

    1970年,AT&T的Bell实验室的 Ken Thompson,以BCPL语言为基础,设计出简单且接近硬件的B语言(取BCPL的首字母),并且他用B语言写了第一个Unix操作系统。

    1972年,Bell实验室的Dennis Ritchie和Ken Thompson共同发明了C语言,并使用C重写Unix。

    1979年,Bjame Stroustrup到了Bell实验室,开始从事将C改良为带类的C(C with Classes)的工作,1983年该语言被正式命名为C++,主要意图是表明C++是C的增强版。

    1985年发布了第一个C++版本。第一个版本的C++,因其面向对象的思想使得编程变得简单,并且又保持了C语言的运行效率,在推出的一段时间内,得到了快速的发展,占据了编程语言界的半壁江山。

    从1985年到1998年,C++从最初的C with Classes新增了很多其他的特性,比如异常处理、模板、标准模板库(STL)、运行时异常处理(RTTI)与名字空间(Namespace)等。

    1998年,C++标准委员会统筹C++的所有特性,发布了第一个C++国际标准C++98。

2. C++ 03

    从1998年到2003年,是C++标准从C++98到C++03的迭代期,期间C++扩增了很多额外的特性,比如以Boost MPL(Boost Metaprogramming Library)与Loki等为代表的模板元编程库的出现,让开发者更加便捷的使用C++在编译期的执行能力,即通过代码编译获得计算结果,学术性的称为模板元编程。到了2003年,C++标准委员会总结最新技术并发布了C++03标准。C++03 是给 C++98 打的补丁,所以现在的人提到 C++98, C++03 往往指的是同一个。

3. C++ 11

    从2003年到2011年,也就是从C++03到C++11,期间C++引入了对象移动、右值引用、lamba表达式(函数式编程)、编译时类型识别(auto)、别名模板以及很多新型关键词(如nullptr、decltype、constexpr)等现代编程语言常具备的能力,让C++与时俱进,开发效率得到了很大的提升。这些新的特性随着C++11标准的发布而被正式确立下来。C++ 11版本也被称为现代C++,而C++ 98/03版本也被称为传统C++。

3.1 nullptr

    实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针。所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针。野指针往往指向的是那些不可用的内存区域,这就意味着像操作普通指针那样使用野指针(例如 &p),极可能导致程序发生异常。C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种:

int *p = 0;
int *p = NULL; //推荐使用

    可以看到,我们可以将指针明确指向 0(0x0000 0000)这个内存空间。一方面,明确指针的指向可以避免其成为野指针;另一方面,大多数操作系统都不允许用户对地址为 0 的内存空间执行写操作,若用户在程序中尝试修改其内容,则程序运行会直接报错。相比第一种方式,我们更习惯将指针初始化为 NULL。值得一提的是,NULL 并不是 C++ 的关键字,它是 C++ 为我们事先定义好的一个宏,并且它的值往往就是字面量 0(#define NULL 0)。 C++ 中将 NULL 定义为字面常量 0,虽然能满足大部分场景的需要,但个别情况下,它会导致程序的运行和我们的预期不符

    由于 C++ 98 标准使用期间,NULL 已经得到了广泛的应用,出于兼容性的考虑,C++11 标准并没有对 NULL 的宏定义做任何修改。为了修正 C++ 存在的这一 BUG,C++ 标准委员会最终决定另其炉灶,在 C++11 标准中引入一个新关键字,即 nullptr。nullptr 是 nullptr_t 类型的右值常量,专用于初始化空类型指针。nullptr_t 是 C++11 新增加的数据类型,可称为“指针空值类型”。也就是说,nullpter 仅是该类型的一个实例对象(已经定义好,可以直接使用),如果需要我们完全定义出多个同 nullptr 完全一样的实例对象。nullptr 可以被隐式转换成任意的指针类型。举个例子:

int * a1 = nullptr;
char * a2 = nullptr;
double * a3 = nullptr;

3.2 auto

    在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。auto 表示变量是自动存储的,这也是编译器的默认规则,所以写不写都一样,一般我们也不写,这使得 auto 关键字的存在变得非常鸡肋。C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不用手动指明变量的数据类型了。auto 关键字基本的使用语法如下:

auto name = value;
int  x = 0;
auto *p1 = &x;   //p1 为 int *,auto 推导为 int
auto  p2 = &x;   //p2 为 int*,auto 推导为 int*
auto &r1  = x;   //r1 为 int&,auto 推导为 int
auto r2 = r1;    //r2 为  int,auto 推导为 int

    name 是变量的名字,value 是变量的初始值。注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。

    auto 的限制

  • 使用 auto 的时候必须对变量进行初始化
  • auto 不能在函数的参数中使用
  • auto 不能作用于类的非静态成员变量
  • auto 关键字不能定义数组,如比如下面的例子就是错误的:
char url[] = "http://c.biancheng.net/";
auto  str[] = url;  //arr 为数组,所以不能使用 auto
  • auto 不能作用于模板参数 

3.3 decltype

    decltype 是 C++ 11新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导。既然已经有了 auto 关键字,为什么还需要 decltype 关键字呢?因为 auto 并不适用于所有的自动类型推导场景,在某些特殊情况下 auto 用起来非常不方便,甚至压根无法使用,所以 decltype 关键字也被引入到 C++11 中。auto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:

auto varname = value;
decltype(exp) varname = value;

    其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。auto 根据=右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟=右边的 value 没有关系。另外,auto 要求变量必须初始化,而 decltype 不要求。这很容易理解,auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。decltype 可以写成下面的形式: 

decltype(exp) varname;

    原则上讲,exp 就是一个普通的表达式,它可以是任意复杂的形式,但是我们必须要保证 exp 的结果是有类型的,不能是 void;例如,当 exp 调用一个返回值类型为 void 的函数时,exp 的结果也是 void 类型,此时就会导致编译错误。C++ decltype 用法举例: 

int a = 0;
decltype(a) b = 1;  //b 被推导成了 int
decltype(10.8) x = 5.5;  //x 被推导成了 double
decltype(x + 100) y;  //y 被推导成了 double
  • 15
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值