c++11新特性

c++11新特性——侯捷

第一讲 primitives

  1. 数量不定的模版参数,可以实现任意个数,任意类型的参数的输入。它可以实现递归。
  2. 模版表达式中的空格, vector<list<int> >以前必须中间有空格,现在可以 vector<list<int>>这么写,也就是不用空格了
  3. nullptr是std::nullptr_t的对象,你可以使用nullptr来代替0或者NULL。有些时候NULL就是定义的为0。
  4. auto的意思是编译器你自己帮我推导一下类型。这也就是实参推导。当然这个最好使用在类型很长或者很复杂你不想写的时候,最好不要什么都使用auto。
  5. 一致性的初始化,c++现在开始推荐你使用{}进行初始化的赋值。以前的方法有很多种。也就是编译器看到{}的时候就会做出一个initializer_list<T>,它关系到一个array<T, n>。
  6. initializer_list相当于是一包东西,也就是数量不定的参数。也可以看作是参数数量不定的容器。
  7. explicit为了构造函数采用一个以上的实参。也就是说,当没有explicit的构造函数,编译器会自动的调用构造函数以满足一些操作,但是,有个这个修饰之后,就是告诉编译器不要自己自作主张的调用构造函数进行转换。编译器可以转换的形式为非显示的单一实参的构造函数,所以也就是这些函数前面不想自动转换就加上explicit。
  8. for(decl:coll){}; for(auto& elem:vec){};这是可以直接改变元素的内容。
  9. =default和=delete,这两个作用在构造函数(可以有多个),拷贝构造,赋值构造和搬移构造函数后面,如果是default就是,即使我已经有了,但是仍然要编译提供的那个,如果是delete就是我不要这个了。一般来说delete很少用,这个函数不要就直接不写了就行了,但是使用delete的方式是会编译通过的。
  10. 一般来说如果一个类有一根指针,那么它一般需要自己定义一下big three。
  11. 浅拷贝,只是逐个字节的拷贝,深拷贝,将指针指向的内容也拷贝过去。
  12. Alias 是一种化名,这种化名是带着一种参数的,它不能被#define所替代
    1
    2
    3
    4
    5
    template<typename T>
    using Vec = std::vector<T, MyAlloc<T>>;
    Vec<int> coll;
    // 上面的也就是等价于
    std::vector<int, MyAlloc<int>> coll;
  13. 模版模版参数是一种比较难得技巧。
  14. noexcept, void foo() noexcept(true); 就是说这个不抛出异常。
  15. 使用上面这个关键字的用途是当你使用搬移构造的时候,如果这个搬移构造没有这个关键字,那么编译器就不会敢使用它,因为出现了问题不知道怎么去处理。当然,这个是vector会尤其使用的。简单说就是,如果你的类有移动构造的时候,最好不要抛出异常。
  16. override,当子类想要重写父类的时候,如果参数写错了,这个时候编译器是不会报错的,所以你在子类中进行父类的重写的时候,在函数后面加上override关键字,就是告诉编译器,你想重写。编译器就会报错了。
  17. final,如果在一个类后面的加上这个关键字,就是说这个类是最后的一个被继承的了,后面不要再继承了。如果把虚函数后面加上final的时候,就是表明,后面继承的时候,这个虚函数不能够被重写。
  18. decltype
  • map<string, float>coll; decltype(coll)::value_type elem; 有点相当于一个typeof的性质。

  • template <typename T1, typenam T2> auto add(T1 x, T2 y)-> decltype(x + y);这种写法也是可以的。

  • typedef typename decltype(obj)::iterator iType; typedef typename T::iterator iType;

  • 使用[ ]是一种lambda函数,

    auto cmp = [ ] (const Person& p1, const Person& p2){{}};

    std::set<Person, decltype(cmp)>coll(cmp);

  1. lambda 函数可以用来参数传递或者一个局部的对象。也就是匿名函数。
    1
    2
    3
    4
    auto I = []{
    std::cout << "hello";
    };
    I();

第二讲 标准库

  1. 右值引用,可以帮助解决不必要的拷贝,当赋值的右边是一个右值的话,那么左手边可以去偷右手边的资源。左值,可以出现在左手边,右值,只能出现在右边。右值,可以是临时对象,常量,以及move(a)。所谓的偷,就是指针的浅拷贝。