c++ primer读书笔记之c++11(一)

1 新的关键词nullptr

c++11引入新的关键词nullptr,用于表示空指针,用于替换之前c提供的NULL(最初NULL是定义在stdlib中的宏定义,通常是0)。

2 新的别名定义机制 alias declaration

c++提供了使用typedef定义的别名机制,但是有时候很难理解。为了更好的使用别名机制,c++11提供了新的别名定义机制,类似代码如下:

  // alias declarations
  using VInt = int; // type alias
  using PInt = int *; // pointer alias
  using RInt = int &; // reference alias
  using MyFunc = int (*)(void); // function pointer alias

  VInt i = 99;
  PInt pi = &i;
  RInt ri = i;
  MyFunc func = nullptr;

3 自动类型推断关键字auto

c++11扩展了auto的函数,编译器可按照实际的初始化参数推断需要的参数类型,并初始化之。其用法类似下面代码:

// item初始化为val1+val2的结果
auto item = val1 + val2;

需要注意的一点是,auto、const以及引用类型一起使用的时候其语法可能不是简单的类型推断,编译器推断类型的机制可能与我们能想到的简单推断不太一致。也就是说如果需要定义auto引用、auto常量时需要明确指定,否则直接使用auto编译器会简单的使用对应的类型,而直接忽略const和引用的限制。相关简单示例代码如下:

  /* auto specifier */
  // a_i is int, a_pi is a pointer to int, a_ri is a reference to int
  auto a_i = 0, *a_pi = &a_i, &a_ri = a_i;
  // error like this, for a_f is float while a_d is double
  //auto a_f = 0.0f, a_d = 0.0;

4 自动类型推断关键字decltype

c++11提供了新的类型推断关键字decltype,主要用于自动推断表达式类型,但不需要初始化的情况(auto提供了推断类型+初始化)。

// result is any type that expr has.
decltype(expr) result;

与auto自动类型推断相比,decltype的自动类型推断很直接,expr是什么类型,通常decltype返回也是一样的类型。用法如下:

  /*decltype specifier*/
  const int ci = 0, &cr = ci, *cp = &ci;
  decltype(ci) x = 0;// x has type const int
  decltype(cr) y = x;// y has type const int &
  decltype(cr) z;// error,z is a reference and must be initialized

  decltype(cr+0) b;// b has type int
  decltype(*cp) c;// error, c is a reference and must be initialized

  int i = 100;
  decltype(i) d;// d has type int
  decltype((i)) e;// error ,e is a reference and must be initialized

需要区分两点,对于有括号的情况、以及指针取值的情况,decltype返回的是左值引用(上面代码中的后两个error)。

5 新的for循环语法,range for

c++本身的for循环需要三个语句,初始化、条件、增量,对于有些操作需要额外写很多代码。针对需要遍历STL容器中的每个元素的情况,可以考虑使用range for。其具体语法如下:

for(declaration:expression)
    statement;

比如我们把std::string的字母全部变成小写字母可以这么写:

  /* range for */
  using std::string;
  string str("UPPER test");
  for (auto &c : str)
      c = tolower(c);

尤其是配合auto和decltype使用,更可以节省很多代码(相信大家都有使用STL迭代器的经验,代码很长,但功能就是为了遍历)。

需要注意一点,range for在使用时不能向容器中插入或删除元素,只能修改。

6 列表初始化机制 list initialization

结合c++11,变量初始化有以下几种方式:

int x = 0;
int x = {0}; // list initialization
int x(0);
int x{0}; // list initialization

针对STL模板定义也提供了新的形势,示例代码如下:

    /* vector */
    vector<vector<int>> ivec;

    // list initialization
    vector<string> strvec{"a", "bc", "def"};
    vector<string> v2{"123"};
    vector<string> v3{5};
    vector<string> v4{5, "s"};  

使用大括号的通常是列表初始化,但是某些情况也不是,比如上例中v3、v4实际调用的vector的构造函数(这是编译器做的处理,在初始化列表中的类型和模板类型不匹配时)。

附加说明

本文内容主要是关于 c++ primer 第五版的前4章中涉及c++11内容的整理。

所有代码都在gcc v4.8.1的版本中编译测试过,相关源码可以从我的git下载,url如下:https://git.oschina.net/Tocy/SampleCode.git,位于c++11目录下的cpp_primer_test1.cpp文件中。

时间: 2024-11-03 20:54:51

c++ primer读书笔记之c++11(一)的相关文章

c++ primer读书笔记之c++11(三)

1 =default构造函数限定符 c++11针对构造函数提供了=default限定符,可以用于显式指定编译器自动生成特定的构造函数.析构或赋值运算函数.参考代码如下: class CtorDftType { public: CtorDftType()=default; CtorDftType(const CtorDftType&)=default; CtorDftType & operator = (const CtorDftType &)=default; ~CtorDftTy

c++ primer读书笔记之c++11(二)

1 新的STL模板类型,std::initializer_list<T> c++11添加了initializer_list模板类型,用于提供参数是同类型情况的可变长度的参数传递机制,头文件是<initializer_list>. 其具体接口可参考cplusplus.com的介绍,地址如下:http://www.cplusplus.com/reference/initializer_list/initializer_list/?kw=initializer_list 与vector不

c++ primer读书笔记之c++11(四)

1  带有作用域的枚举 scoped-enumeration 相信大家都用过枚举量,都是不带有作用域的,在头文件中定义需要特别注意不要出现重名的情况.为了解决这种问题,c++11提供了带作用于的枚举.可以使用class EnumName定义,示例代码如下: enum {ZERO, ONE, TWO}; enum class color {RED, BLUE, GREEN}; 上面的是没有作用域的枚举定义形式,下面是带有作用域的枚举定义形式,调用带有作用域的枚举必须指定作用域,否则会编译出错. 还

C++ Primer 读书笔记:第11章 泛型算法

第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数. 2.常用的泛型算法函数: fill,fill_n, copy, replace, sort, unique, count_if, stable_sort 此外在有一个谓词函数会结合以上的函数使用,像sort, count_if等 3.再谈迭代器 (1)插入迭代器 back_inserter, f

C++ primer读书笔记10-继承

封装,继承,多态是C++的三大基本概念,这里着重总结一下继承相关的东西 1 类派生列表 类派生列表指定派生类要继承的基类,派生列表中有一个或者多个基类如: class B : public A1,protected A2,private A3 但是单继承时最常见的,多继承不多见 2 派生类的定义 派生类继承时,会包含父类的所有成员,即便私有成员不能被访问.父类中的虚函数,在派生类中一般也要定义,如 果不定义的话,派生类将继承基类的虚函数 3 基类必须是已经定义的 一个仅仅声明的类,是不能出现在派

C++primer读书笔记11-多态

多态也是C++中的一个重要的方面,多态和动态类型,虚函数本质上是指相同的事情. 1 虚函数 类中的成员函数原型前面加上virtual 表面这个函数是个虚函数.虚函数的目的是为了在继承它的派生类中重新定义这个函数,以便于通过基类的指针或引用在运行时对派生类的函数进行调用. 2 派生类和虚函数 派生类一般情况下要重定义所继承的虚函数,有几个注意事项. <1>虚函数的声明必须和基类中的函数声明原型完全一致,例外的是当基类返回基类型的指针或者引用的时候,派生类可以派生类类型的指针或者引用 <2&

C++中的volatile(Primer读书笔记)

时间:2014.05.24 地点:基地 -------------------------------------------------------------------------- 一.简述 volatile限定符平时很少用到,今天倒是碰到了,所幸探个明白.volatile 英文字面意思是"不稳定的",确切的计算机含义时与机器相关,所以在对包含volatile的程序在移植到新机器或使用不同的编译器时往往还需要对编译器进行一些改变. -----------------------

C++primer读书笔记9转换与类类型

有时候指定了自己类类型来表示某种类型数据如SmallInt,那么为了方便计算就会指定一个转换操作符,将该类类型在某种情况下自动的转换为指定的类型 <1>转换操作符 operator type(); 转换函数必须是类成员函数,不能指定返回类型,并且形参列表必须为空,并且通常不应该改变转换对象,所以操作符通常定义为const成员. #include <iostream> using namespace std; class SmallInt { public: SmallInt(int

C++ Primer读书笔记整理(二)

8.数组 标准库begin和end函数可作用于数组,分别用于获取指向数组首元素和尾元素下一位置的指针. 例如: int ia[] = {0, 1, 2, 3, 4}; int *beg = begin(ia); //beg指向数组首元素 int *e = end(ia); //e指向数组尾元素下一位置 begin和end函数定义在头文件iterator中. 另外:可以使用数组来初始化vector的对象: int arr[] = {0, 1, 2, 3, 4, 5}; vector<int> i