• 《深入理解C++11》要点总结


    3.1 继承构造函数
         通过using关键字可以继承父类的构造函数。也可以通过显式定义构造函数来阻止继承。
    3.2 委派构造函数,减少构造函数的书写
    class Info {
    public:
        Info() { InitReset(); }
        Info(int i) : Info() { type = i; }  //通过调用无参构造函数,可以减少构造函数内容的重写
        Info(char e) : Info() { name = e; }  //委派构造函数和初始化列表不能同时存在,使用委派构造函数后,初始化代码需要放在函数体中
     
    private:
        int type { 1 };         //初始化成员变量
        char name { 'a' };
     
        void InitReset() {}
    };
    3.3.2 移动语意学
         通过移动构造函数可以减少临时对象中的数据拷贝。
    3.3.3 左值、右值和右值引用
         有名字的可以取地址的是左值(&a),没有名字,不能取地址的是右值( &(b+c)是错误操作 ),所以a是左值,(b+c)是右值
         T && a = ReturnRvalue(); //获得一个右值引用,只有在a的生命周期中,函数返回的右值持续存活
         右值引用不能绑定左值,如 int c; int && d = c;  //错误
         可以通过<type_traits>中的模板类来判断值的类型,如 is_rvalue_reference<string &&>::value;
    3.3.4 std::move 将一个左值强制转化为右值引用,从而可以通过右值引用使用该值
         如果声明了移动构造函数、移动赋值函数、拷贝赋值函数和析构函数中的一个或多个,编译器不会再生成默认的拷贝构造函数。所以拷贝构造/赋值和移动构造/赋值函数必须同时提供或者都不提供。
    3.5 列表初始化
         等号加上赋值表达式,如 int a = 3 + 4;
         等号加上花括号,如 int a = {3+4};
         圆括号式的表达式 ,如 int a (3+4);    可以用于堆内存的new操作,如 int *i = new int(1);
         花括号式的表达式,如int a {3+4};     double *d = new double{2.3f};
     
         使用列表初始化,在出现类型收窄时会编译失败,如 char c = {1024}; //无法通过编译
    3.8 字面量操作符  ret operator “” _x(arguments) {} 可以定义字面量操作符
    struct Watt {
        unsigned int v;
    };
     
    Watt operator "" _w(unsigned long long v)
    {
        return { (unsigned int)v };
    }
         如果字面量为整型数,那么字面量操作符函数只可以接受unsinged long long或const char*为参数
         如果字面量为浮点型数,函数只可接受long double或const char*为参数
         如果字面量为字符串,函数只接受const char*, size_t为参数
         如果字面量为字符,函数只可以接受一个char为参数
     
    4.2 auto 自动类型推导
         使用auto声明的变量必须被初始化,从而使编译器能够从初始化表达式中推导出其类型
         auto可以用于new关键字,auto z = new auto(1);
         auto不能用作形参的类型,即使提供了默认参数,如  void fun(auto x = 1) {} //编译失败
         auto也不能用于结构体的非静态成员变量,即使成员拥有初始值,如 struct str { auto var = 10; } //编译失败
         不能声明auto数组
         在实例化模板的时候不能使用auto作为模板参数,如 vecotr<auto> v = {1};  //编译失败
    4.3 decltype可以用于获取对象类型,获取的类型可以用于定义对象,如 vector<int> vec; typedef decltype(vec.beging()) vectype;
         decltype只接受表达式作为参数(如,decltype( Func(x)),而不接受 decltype( Func ) ),和auto一样在编译时确定类型
    4.4 追踪返回类型,使用auto和decltype可以追踪返回类型
    template<typename T1, typename T2>
    auto Sum(T1 & t1, T2 & t2) -> decltype(t1 + t2) {
        return t1 + t2;
    }

    auto (*fp)() -> int;  等价于  int (*fp)();

     
    5.1 强类型枚举
         enum class Type: char { General, Light, Medium, Heavy };
     
    6.1.2 常量表达式函数 constexpr
         函数必须有返回值
         函数体只有单一的return返回语句,函数体只有一条语句,且这条语句是return。可以有static_assert
         在使用前必须已有定义
         return 返回语句表达式中不能使用非常量表达式的函数、全局数据,且必须是一个常量表达式
         常量表达式的构造函数约束:函数体必须为空;初始化列表只能由常量表达式来赋值。
    6.1.3 常量表达式值
    const int i = 1; 与 constexpr int j = 1; 大部分情况下相同,区别是如果 i 在全局名字空间中,编译器一定会为 i 产生数据,而对于 j ,如果不是有代码显示地使用了它的地址,编译器可以选择不为它产生数据,而仅将其当做编译器的值。
    6.2.2 变长模板
         template <typename… Elements> class tuple;   // Elements为模板参数包
    6.3.2 原子操作 atomic
         atomic_llong total {0}; //原子数据类型,多线程访问时不需要加锁
         std::atomic<T> t; //atomic类模板,可以任意定义出需要的原子类型
         原子类型只能从其模板参数类型中进行构造,不允许原子类型进行拷贝构造、移动构造以及使用operator=等。
     
    7.1.2 nullptr
         nullptr不能转换为非指针类型,即使使用 reinterpret_cast<nullptr_t>()的方式也不可以
         nullptr不适用于算术运算表达式,也不能进行取地址操作
    7.2.2 =default 显式的声明函数为缺省函数,=delete 显式的声明函数为删除函数(不可使用和重载)
         显示删除也可以避免编译器做一些不必要的隐式数据类型转换,此时不要和explicit共同使用,如 void Func(char c) = delete; 会导致 Func(‘c’);无法通过编译
    7.3.2 lambda函数
         [capture] (parameters) mutable ->return-types {statement}
         lambda和仿函数类似,实际上仿函数是编译器实现lambda的一种方式
         对于按值方式传递捕捉列表,传递的值在lambda函数定义的时候就决定了,而按引用方式传递的值则等于lamdba函数调用时的值。
         lambda的捕捉列表仅能捕捉父作用域的自动变量,而对超出这个范围的变量是不能被捕捉的。
     
    8.1.1 alignas 可以设定结构体的对齐方式,alignof获取结构体的对齐大小
    struct alignas(32) AlignedColorVector {
        double r;
        double g;
        double b;
        double a;
    };
    8.2.2 通用属性,使用左右双中括号包含
    [[ attribute-list ]]
    [[ attr1 ]] void fun [[ attr2 ]] ();
    [[ attr1 ]] int array [[ attr2 ]] [10];
    C++11中的预定义通用属性包括 [[ noreturn ]] 标识不会返回的函数,[[ carries_dependency ]] 标识不会将控制流返回给原调用函数的函数,如
    [[ noreturn ]] void ThrowAway() {
         throw "exception”;
    }
    8.3.2 UTF-8 采用的变长存储方式,无法通过数字式访问读取数据,更多的使用序列化时节省存储空间。定长的UTF-16或UTF-32更适合在内存环境中操作。
     
    其他:
         在C++11中std的bind1st和bind2st被bind模板所代替 
  • 相关阅读:
    【翻译自mos文章】rman 标准版和企业版的兼容性
    HDU 1010 Tempter of the Bone
    uva 10716 Evil Straw Warts Live(贪心回文串)
    适配器及适配器模式
    Android推送技术研究
    【hadoop2.6.0】倒排索引遇到问题了
    【hadoop2.6.0】MapReduce原理
    【hadoop2.6.0】一句话形容mapreduce
    【leetcode】Median of Two Sorted Arrays(hard)★!!
    【leetcode】Merge k Sorted Lists
  • 原文地址:https://www.cnblogs.com/vectorli/p/5524481.html
Copyright © 2020-2023  润新知