C++11 新特性笔记
- 初始化列表
- 统一初始化
- auto
- 基于范围的for循环
- nullptr
- 强类型枚举
- 静态断言
- 委托构造函数
- Override
- final
- 默认构造函数
- 被删除的函数
- constexpr
- 字符串字面量
- lambda 函数
初始化列表
C++11 添加了 initializer_list 类型,允许使用 initializer_list 初始化对象
STL 容器例如 map, vector 等都实现了 initalizer_list constructor
自定义的对象也可以使用 initalizer_list 作为构造函数的参数
1 | vector<int> v = {1, 2, 3}; |
统一初始化
C++03 中,可以使用集合初始化
1 | struct A{ |
C++11 允许通过同样的方式调用构造函数
1 | struct A{ |
连同初始化列表,统称为统一初始化
统一初始化调用顺序优先级:
- initalizer_list constructor
- 构造函数
- 集合初始化
auto
非常实用的功能, 从复制操作的右值直接推断变量类型
1 | auto a = 1; |
在 C++03 中,一个痛点:要迭代一个容器,需要
1 | for(std::set<int>::iterator it = map.begin(); it != map.end(); ++it) {/* Do something */} |
在 C++11 中,可以直接使用 auto
1 | for(auto it = map.begin(); it != map.end(); ++it) {/* Do something */} |
基于范围的for循环
对于任何一个带有 begin() 和 end() 方法的对象,例如 vector
1 | vector<int> v = {1, 2, 3}; |
配合 auto 使用效果更佳
nullptr
在 C++03 中, 使用 NULL 代表空指针, NULL 被定义为 0, 有时候会有歧义
在 C++11 中, 使用专门的 nullptr 代表空指针, 用以解决以下问题
1 | void func(int i) {} |
强类型枚举
C++03 中,枚举常量被暴露在同一作用域中,且被隐式转化为整形
1 | enum Color{red, blue}; |
C++11 引入了 enum class 解决这个问题
1 | enum Color{red, blue}; |
静态断言
C++11 允许使用 static_assert 在编译期执行断言
1 | assert(myPointer != nullptr); // 运行期断言 |
委托构造函数
在 C++03 中,如果两个构造函数都需要执行相同的操作,只能
1 | class A { |
额外定义的 init() 函数可能被误调用
C++11 则允许在构造函数开头调用另一个构造函数, 也允许在声明时初始化成员变量
1 | class A { |
Override
C++11 引入了 override 关键字,避免继承时错误的创造新函数
1 | class A { |
final
C++11 引入 final 关键字,用于修饰类和虚函数,表示不允许继承/重载
1 | class Dog final { // Dog 不可继承 |
默认构造函数
C++11 允许使用 default 关键字,由编译器自动生成默认构造函数
1 | // C++03 |
被删除的函数
C++03 中, delete 关键字仅用于释放动态分配的内存
C++11 允许使用 =delete 将函数标记为被删除的, 可以用来阻止隐式类型转换等
1 | class Dog { |
constexpr
C++11 中, constexpr 扩展了原有 const 的用法, 允许在编译期对作用于常量的函数求值
1 | constexpr int a() {return 3;} |
字符串字面量
C++11 引入了更多的字面量定义方式,方便定义 unicode 字符串以及正则表达式等
1 | const char *a = u8"你好"; // UTF-8 |
lambda 函数
C++11 引入了 lambda function,方便定义匿名函数
1 | auto f = [](int x, int y){return x + y;}; |