C++11 New Features

最近因为工作需要,重新看了看C++ 11的特性(C++ Primer)。想做一些笔记,就顺道记在这里,对自己对读者也便于温习。

long long

C++11 定义了long long类型,并规定规范:long long至少比long大。

constexpr 常量

在C++中,存在常量表达式(const expression),用于指哪些值不会改变并且在编译过程就能得到计算结果的表达式。举几个例子:

1
2
3
4
const int max_files = 20; // 是常量表达式
const int limit = max_files + 1 // 是常量表达式
int staff_size = 27; // 不是常量表达式
const int sz = get_size(); // 不是常量表达式

在一个复杂的工程中,很难分辨一个初始值是否是常量表达式,因此显式地定义constexpr就很有必要,这样也会在编译阶段强制要求编译器去验证是否是常量类型,且是否由常量表达式初始化。

空指针

得到空指针的几个例子:

1
2
3
int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL;

C++11提供nullptr用于初始化空指针

列表初始化(list initialization)

现在初始化变量可以用以下四种方式:

1
2
3
4
int units_sold = 0;
int units_sold = {0};
int units_sold(0);
int units_sold{0};

当list initialization用于内置类型的变量时,这种初始化形式在初始化值存在丢失信息的风险时,可以在编译阶段就让编译器报错。

类型别名(type alias)

1
2
typedef double wages;
using wages = double;

现在以上两种方法都可以对类型进行别名定义。

auto类型说明符

1
auto item = val1 + val2; // item初始化为val1和val2相加的结果

auto定义的变量显然必须要有初始值,才能让编译器根据初始值去parse变量类型。

decltype类型指示符

decltype的作用是选择并返回操作数的数据类型。在这个过程中,编译器分析表达式并得到它的类型,但并不实际计算表达式的值:

1
2
3
const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x的类型是const int
decltype(cj) y = x; // y的类型是const int&

类内初始值(in-class initializer)

在C++11标准中,允许类内初始值初始化数据成员。没有初始化的成员被默认初始化。

1
2
3
4
5
struct Sales_data {
std:: string bookNo; // 将会被默认初始化为空字符串
unsigned units_sold = 0;
double revenue = 0.0;
}

范围初始化

范围for(range for)语句的语法规则如下:

1
2
3
for (declaration : expression) {
statement here;
}

其中,expression应该是一个序列的类型,declaration部分负责定义一个变量,改变量将被用于访问序列中的基础元素。每次迭代,declaration部分的变量被初始化(默认为拷贝初始化)为expression部分的下一个元素值。

使用=default生成默认构造函数

传统的C++ class使用编译默认的合成默认构造函数(synthesized default constructor)来当作一个未定义构造函数的类的默认构造函数。在C++11的新标准中允许使用=default修饰符来显示指定一个类的默认构造函数。如下:

1
2
3
4
5
6
struct Sales_data {
Sales_data() = default;
std::string bookNo;
unsiged units_sold = 0;
double revenue = 0.0;
}

shared_ptr类

shared_ptr是一种智能指针(smart pointer)类型。用于管理动态对象。智能指针的行为类似于常规指针,但最重要的区别是其内部对所指向的对象提供一个引用计数且提供根据引用计数自动释放所指对象的功能。

常用的方式:

1
2
3
shared_ptr<int> p3 = make_shared<int>(42); // 42
shared_ptr<string> p4 = make_shared<string>(10, '9'); // "9999999999"
shared_ptr<int> p5 = make_shared<int>() // default 0