C++11 初探

C++11 列表初始化

  • 初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

  • 定义一个int变量并初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int a = 0;
    int a = {0};
    int a(0);
    int a{0};

    int b[] = {1, 2, 3};
    int b[]{1, 2, 3};

    int c(3.1234567); //警告, 编译器会有警告信息
    int c{3.1234567}; //错误,编译器会报错
  • 初始化对象或者给对象赋新值,都可以使用一组由花括号括起来的初始值。

  • 当用于内置类型的变量时,这种初始化方式存在一个重要特点:如果使用列表初始化且初始值存在丢失信息的风险,则编译器会报错。

C++11 constexpr 变量

  • 将变量声明为constexpr类型以便由编译器来检验变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
  • 常量表达式的值需要在编译时就得到计算,因此对声明constexpr时用到的类型必须有所限制。因为这些类型一般比较简单,值也显而易见、容易得到,这些类型称为”字面值类型”
  • 算数类型、引用和指针都属于字面值类型。指针和引用定义为constexpr,它们的初始值受到严格限制。一个constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址中的对象。
  • 在constexpr定义了一个指针,限定符constexpr仅对指针有效,与指针所指对象无关。
1
2
const int *p = nullptr;     //p是一个指向整型常量的指针 *p不可改变 p可以改变
constexpr int *q = nullptr; //q是一个指向整数的常量指针 等同于 int * const q = nullptr; *q可以改变 q不可改变

C++11 nullptr

  • 空指针不指向任何对象。

  • 生成空指针的方法:

    1
    2
    3
    4
    int *p = nullptr;
    int *p = 0;
    //需要包含cstdlib头文件
    int *p = NULL;
  • nullptr是一种特殊类型的字面值,可以被转化成任意其他的指针类型。

  • NULL欲处理变量在cstdlib中定义,实际值就是0,因此用NULL初始化指针和用0初始化是一样的。新标准下最好使用nullptr,同时尽量避免使用NULL。

C++11 类型别名

  • 类型别名是一个名字,它是某种类型的同义词。使用类型别名可以使复杂的类型名字简单明了、易于理解和使用,有助于程序员清楚的知道使用该类型的真实目的。

  • 两种定义类型别名的方法:

    1. typedef
    2. 别名声明 using
      1
      2
      typedef double mydouble;
      using mydouble = double;
  • 指针、常量和类型别名

    1
    2
    3
    typedef char *pstring;
    const pstring cstr = 0; //cstr的类型为 char *const 而不是 const char*
    const pstring *ps; //ps的类型为 char *cosnt* 而不是 const char**

C++11 auto

  • auto类型说明符,让编译器分析表达式所属的类型。auto让编译器通过初始值类推算变量的类型。auto定义的变量必须有初始值。

  • 使用引用其实是使用引用的对象,此时编译器以引用对象的类型做为auto的类型。

  • auto一般会忽略顶层const, 底层const则会保留下来。如果需要推断出的auto类型是一个顶层const,需要明确指出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int i = 0, &r = i;
auto a = r; // int a

const int ci = i, &cr = ci;
auto b = ci; // int b = ci;
auto c = cr; // int c = cr;
auto d = &i; // int *d = &i;
auto e = &ci; // const int *e = &ci;

const auto f = ci; // const int f = ci;

auto &g = ci; // const int &g = ci;
//auto &h = 42; 错误,不能为非常量引用绑定字面值
const auto &j = 42; // const int &j = 42;

auto k = ci, &l = i; // int k = ci, &l = i;
auto &m = ci, *p = &ci; // const int &m = ci, *p = &ci;
//auto &n = i, *p2 = &ci; 错误,i的类型是int,而&ci的类型为const int