C++标准
1. C++标准简介
The document specifies requirements for implementations of the C++ programming language.
美国国家标准局(American National Standards Institute, ANSI) 在1990年设立了一个委员会(ANSI X3J16),专门负责制定C++标准(ANSI制定了C 语言标准)。国际标准化组织(the International Organization for Standardization, ISO) 很快通过自己的委员会(ISO-MG-21) 加入了这个行列,创建了联合组织 ANSI/ISO,致力于制定C+标准。
第一版,国际标准 ISO/IEC 14882:1998,于 1998 年获得 ISO、IEC(the International Electrotechnical Commission, 国际电工技术委员会) 和ANSI的批准。该标准常被称为C++98,它不仅描述了已有的 C++特性,还扩展了C++、添加了异常、运行阶段类型识别(RTTI)、模板和标准模板库(STL)。
第二版,ISO/IEC 14882:2003,对C++98的技术性修订,主要修订错误,减少多义性,没有改变语言特性,该版本称为C++03.
第三版,ISO/IEC 14882:2011,2011年9月11日正式发布,增加了许多新的语言特性。该版本称为C++11,还曾被称为C++ 0x,x曾预期为7或8.
第四版,ISO/IEC 14882:2014,在11基础上进行细微的完善和改进,该版本称为C++14. 包括:允许二进制字面量int var = 0b110;
'0b'或 '0B'开头,但只能用来表示整型。
第五版,ISO/IEC 14882:2017,增加了一些特性,如允许命名空间嵌套定义,用新语法来定义函数的异常规格,引入新语法-推断指引(Deduction Guildes)等。该版本称为C++17.
第六版,ISO/IEC 14882:2020,2020年12月发布。官方文档ISO/IEC 14882:2020(en), Programming languages — C++.
第七版,ISO/IEC DIS 14882,正在开发中。ISO官网 https://www.iso.org/standard/83626.html
扩展:c++14新增语法和标准库特性_-飞鹤-CSDN博客
2. C++11新特性
-
统一的列表初始化方式。扩大了列表初始化的适用范围,使其可用于所有内置类型和用户定义的类型(类的对象)。并且,使用初始化列表时,可添加等号”=”,也不省略。
int x1 = {5}; int x2 {55}; short nums[3] {1,2,3};
列表初始化禁止缩窄变换,即一个较大的数放进一个较小类型的变量里,但允许较窄类型的数放进较宽类型的变量里。
类对象也可使用列表初始化。若类的某个构造函数接收模板类initializer_list作为函数的参数,则初始化列表语法只能用于该构造函数。
-
关键字声明
auto以前是一个存储类型说明符,动态存储,C++11将其用于自动类型推断,必须进行显式初始化。
decltype根据表达式类型定义变量类型。在使用模板函数时很方便,推导变量类型。
decltype(x*n) y; // y的类型是x*n表达式的类型。
-
函数的返回类型后置
double f1(double, int); auto f1(double, int) –> double;
-
此前,typedef可用于给数据类型起别名,现增加一种创建别名的语法 using = :
using itType = vector<string>:: iterator;
using 还可用于给模板类起别名,如vector、array等。
-
nullptr空指针
空指针是不会指向有效数据的指针。此前,使用0来表示该指针,但和整型的0冲突。C++11新增nullptr表示空指针,是指针类型,不可转换为整型。仍允许使用0来表示空指针,为向后兼容,因此nullptr==0 为true。
-
智能指针
new的内存需要程序员显式delete释放,旧版本提供auto_ptr来自动完成该过程,但C++11废弃auto_ptr,新增3种智能指针unique_ptr,shared_ptr,weak_ptr。
auto_ptr,unique_ptr,shared_ptr相当于对象,当指针的生命周期到时时,(在局部函数里,函数调用结束,栈释放,auto_ptr等自然不复存在),指针的析构函数将使用delete来释放所指向的内存空间。
auto_ptr<int> pt (new int);
需
#include <memory>
,智能指针模板位于名称空间std中。智能指针定义时当作对象,使用时当作普通指针即可。由于智能指针会自动释放堆内存,要严格注意指针间赋值操作。但普通指针不需要有这种困扰。
unique_ptr采用所有权模型,在一个作用域内,只能有一个指针指向同一块堆内存,unique_ptr在编译期检错;auto_ptr采用所有权模型,在运行期检错;shared_ptr,采用引用计数,允许多个指针指向同一块堆内存。
-
作用域内的枚举enum
以前,同一作用域中不同枚举类型的成员不能重名。由于不同的实现可以选择不同的底层类型,因此枚举可能不能完全移植。C++新增枚举声明,添加class或struct定义。
enum class color {red, yellow, blue};
引用特定枚举值需要显式使用限定符,如New1::never, New2::never.
-
类
C++11允许类定义里初始化成员变量,但构造函数里对成员变量的修改会覆盖初始化的值。
-
右值引用
传统的引用可关联左值,左值可出现在赋值语句的左边,可获取地址。但const常量可获取地址,但不能赋值。
const int b = 0; const int & rb = b; // 引用前必须也加const
C++11新增右值引用,用&&表示,右值是可以出现在”=”右边,但不能对其应用地址运算符的值,包括字面常量(C风格字符串除外,它表示地址)、表达式、返回类型为数值类型的函数。
int && rt = 13; // 相当于int rt = 13; rt可以获取地址。改变值。
引入右值引用的主要目的是实现移动语义。
-
移动语义允许将1个对象的资源所有权从自己转移到另一个对象,而不需进行昂贵的复制操作。
std::move()
,如unique_ptr智能指针。拷贝构造函数:创建新对象,分配内存和复制数据
移动构造函数:使用右值引用来接收1个临时对象或1个即将被销毁的对象,将其资源所有权转移到新对象中。只涉及指针的复制。
-
模板类和标准模板库(STL, Standard Templates Library)
C++11新增STL容器unordered_map, unordered_multimap, unordered_set, unordered_multiset, forward_list(单向链表,对比于双向链表list)。前4种使用哈希表实现。新增模板array(就是个数组array<int, 5>,定义之后长度不可变,因此没有push_back等方法)。
对于内置数组,含有方法begin(), end()的类,如string,和STL容器,可使用
for(auto/type x: container)
循环,若要修改x的值,则使用引用for(auto/type &x: container)
。新增cbegin(), cend(),是begin(), end()的const版本,防止对原容器的元素进行误改等操作。
begin(), end(), 分别指向容器的第一个元素,容器最后一个元素的后面。rbegin(), rend(), 分别指向容器的最后一个元素,容器第一个元素的前面,联合使用达到逆序遍历的效果。crbegin(), crend()是其const版本。
旧版使用嵌套模板时,尖括号要用空格分开,防止与运算符”>>”混淆,
vector<list<int> > vec;
C++11不再要求,
vector<list<int>> vec;
-
多线程
新增 线程支持库<thread>, <mutex>, <condition_variable>和<future>
新增 原子操作库
关键字thread_local,静态存储,与每个线程绑定一个,持续性和绑定的线程一致。
-
Lambda表达式/Lambda函数
lambda函数也叫lambda表达式,就是匿名函数。C++11中,对于接收函数指针或函数符(STL中函数对象)作为参数的函数,可以使用lambda作为参数。
lambda表达式定义的地方和调用的地方在同一个地方,便于调试和修改代码。通常lambda没有名字,也可给lambda指定名称。
auto func = [] (int x) {return x % 3 == 0;}; // 给lambda指定名称func bool res = func(3);
当lambda函数体只有一条语句时,如只有一条return,可不显式写返回类型,由decltype推断。否则,需要显式写返回类型,采用返回类型后置的格式,如下:
[] (int x) –> int {x = 1; return x % 3;};
lambda捕获方式主要有三种:值捕获、引用捕获和隐式捕获,使lambda函数体内可使用外部所有动态变量。有两种方式传入外部变量,一种是引用&,一种是值=,如果只传特定变量(显式捕获),则传值方式时可省略=(值捕获),传引用方式不可省略&(引用捕获)。传全部的外部变量时(隐式捕获),值方式用“=”标识所有变量,引用方式用“&”。捕获的变量放进 [] 里声明。文章来源:https://www.toymoban.com/news/detail-506222.html
[m,&n] (int x) –> int {x = m; return x % 3;}; // 值捕获:m传值,引用捕获:n传引用 [=] (int x) –> int {x = n; return x % 3;}; // 隐式捕获:外部所有变量都通过值方式传递 [&] (int x) –> int {x = n; return x % 3;}; // 隐式捕获:外部所有变量都通过引用方式传递 [=,&n] (int x) –> int {x = n; return x % 3;}; // 表示n以引用方式传递,剩余变量以值方式传递 // 隐式捕获与显式捕获混用时,隐式捕获必须是[]里第一个参数
一些注意事项和详细例子:C++ lambda表达式详细讲解2-隐式捕获与显式捕获-bingma03的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-506222.html
到了这里,关于C++语言执行标准的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!