• C++11--20分钟了解C++11 (下)


    20分钟了解C++11

    9 override关键字 (虚函数使用)

     *
     * 避免在派生类中意外地生成新函数
     */
    // C++ 03
    class Dog {
       virtual void A(int);
       virtual void B() const;
    }
    
    class Yellowdog : public Dog {
       virtual void A(float);  // 生成一个新函数
       virtual void B(); //生成一个新函数
    }
    
    
    // C++ 11
    class Dog {
       virtual void A(int);
       virtual void B() const;
       void C();
    }
    
    class Yellowdog : public Dog {
       virtual void A(float) override;  // Error: no function to override
       virtual void B() override;       // Error: no function to override
       void C() override;               // Error: not a virtual function
    }
    

    10 final (虚函数和类使用)

    
    class Dog final {    // 在类名后添加表示不能再从该类派生子类
       ...
    };
       
    class Dog {
       virtual void bark() final;  // 在虚函数后添加表示该函数不能再被覆写
    };
    

    11 编译器生成默认构造函数

    class Dog {
       Dog(int age) {}
    };
    
    Dog d1;  // 错误:编译器不会自动生成默认构造函数,因为已经有构造函数了
    
    
    // C++ 11:
    class Dog {
       Dog(int age);
       Dog() = default;    // 强制编译器生成默认构造函数
    };
    

    12 delete 禁用某些函数

    
    class Dog {
       Dog(int age) {}
    }
    
    Dog a(2);
    Dog b(3.0); // 3.0会从double类型转成int类型
    a = b;     // 编译器会生成赋值运算符
    
    
    // C++ 11 手动禁用:
    class Dog {
       Dog(int age) {}
       Dog(double ) = delete;
       Dog& operator=(const Dog&) = delete;
    }
    

    13 constexpr 常量表达式

    int arr[6];    //OK
    int A() { return 3; }
    int arr[A()+3];   // 编译错误
    
    // C++ 11
    constexpr int A() { return 3; }  // 强制计算在编译时发生
    
    int arr[A()+3];   // 生成一个大小为6的数组
    
    
    // 利用constexpr写更快的程序
    constexr int cubed(int x) { return x * x * x; }
    
    int y = cubed(1789);  // 在编译时计算
    
    //cubed()函数:
    //1. 非常快,不消耗运行时计算
    //2. 非常小,不占据二进制空间
    

    14 新的字符串字面值

      // C++ 03:
      char*     a = "string";  
    
      // C++ 11:
      char*     a = u8"string";  // UTF-8 string. 
      char16_t* b = u"string";   // UTF-16 string. 
      char32_t* c = U"string";   // UTF-32 string. 
      char*     d = R"string \"    // raw string. 
    
    

    15 lambda函数

    cout << [](int x, int y){return x+y}(3,4) << endl;  // Output: 7
    auto f = [](int x, int y) { return x+y; };
    cout << f(3,4) << endl;   // Output: 7
    
    
    template<typename func>
    void filter(func f, vector<int> arr) {
       for (auto i: arr) {
          if (f(i))
             cout << i << " ";
       }
    }
    
    int main() {
       vector<int> v = {1, 2, 3, 4, 5, 6 };
    
       filter([](int x) {return (x>3);},  v);    // Output: 4 5 6
       ...
       filter([](int x) {return (x>2 && x<5);},  v); // Output: 3 4
    
    
       int y = 4;  
       filter([&](int x) {return (x>y);},  v);    // Output: 5 6
       //注: [&] 告诉编译器要变量捕获
    }
    
    // Lambda函数几乎像是一个语言的扩展,非常方便
    // template
    // for_nth_item
    

    17 用户自定义的字面值

    
    // C ++在很大程度上使用户定义的类型(类)与内置类型的行为相同.
    // 用户自定义的字面值使其又往前迈出一步
    
    //老的C++,不知道到底表示多长?
    long double height = 3.4;
    
    // 在学校物理课的时候
    height = 3.4cm;
    ratio = 3.4cm / 2.1mm; 
    
    // 为什么在编程时不这么做?
    // 1. 语言不支持
    // 2. 单位转换需要运行时开销
    
    
    // C++ 11:
    long double operator"" _cm(long double x) { return x * 10; }
    long double operator"" _m(long double x) { return x * 1000; }
    long double operator"" _mm(long double x) { return x; }
    
    int main() {
       long double height = 3.4_cm;
       cout << height  << endl;              // 34
       cout << (height + 13.0_m)  << endl;   // 13034
       cout << (130.0_mm / 13.0_m)  << endl; // 0.01
    }
    
    //注: 加constexpr使单位转换在编译时计算
    
    
    // 限制: 只能用于以下参数类型:
       char const*
       unsigned long long
       long double
       char const*, std::size_t
       wchar_t const*, std::size_t
       char16_t const*, std::size_t
       char32_t const*, std::size_t
    // 返回值可以是任何类型
    
    
    // 例子:
    int operator"" _hex(char const* str, size_t l) { 
       // 将十六进制格式化字符串str转成int ret
       return ret;
    }
    
    int operator"" _oct(char const* str, size_t l) { 
       // 将格式化8进制字符串str转成 int ret
       return ret;
    }
    
    int main() {
       cout << "FF"_hex << endl;  // 255
       cout << "40"_oct << endl;  // 32
    }
    
    

    18 可变参数模板 Variadic Template

     *
     * 可以接受任意个数的任意类型模板参数的模板
     * 类和函数模板都可以是可变的
     */
    template<typename... arg>
    class BoTemplate;
    
    BoTemplate<float> t1;
    BoTemplate<int, long, double, float> t2;
    BoTemplate<int, std::vector<double>> t3;
    
    BoTemplate<> t4;
    
    
    // 可变参数和非可变参数组合
    template<typename T, typename... arg>
    class BoTemplate;
    
    BoTemplate<> t4;  // Error
    BoTemplate<int, long, double, float> t2;  // OK
    
    
    // 定义一个默认模板参数
    template<typename T = int, typename... arg>
    class BoTemplate;
    

    19 模板别名 Template Alias

      template<class T> class Dog { /* ... */ };
      template<class T>
        using DogVec = std::vector<T, Dog<T>>;
    
      DogVec<int> v;  // 同: std::vector<int, Dog<int>>
    

    20 decltype

     * 相当于GNU typeof
     */
      const int& foo();      // 声明一个函数foo()
      decltype(foo())  x1;  //  类型是const int&
    
      struct S { double x; };
      decltype(S::x)   x2;  //  x2类型double
    
      auto s = make_shared<S>();
      decltype(s->x)   x3;  //  x3类型double
    
      int i;
      decltype(i)      x4;  //  x4类型int  
    
      float f;              
      decltype(i + f)  x5;   // x5类型float
    
      // decltype对于模板泛型编程非常有用
      template<type X, type Y>
      void foo(X x, Y y) {
         ...
         decltype(x+y) z;
         ...
      }
    
      // 如果返回值要使用decltype?
      template<type X, type Y>
      decltype(x+y) goo(X x, Y y) {      // 错误:x 和 y 未定义
         return  x + y;
      }
    
      // auto和decltype组合实现具有尾随返回类型的模板
      template<type X, type Y>
      auto goo(X x, Y y) -> decltype(x+y) {
         return  x + y;
      }
    
    
  • 相关阅读:
    关于JQuery的autocomplete1.11.4版本插件的使用心得
    BUG:ie678 使用jQuery设置页面标题
    BUG:ie8不支持indexOf()
    【转】使用@import和link导入样式
    【转】css3 media媒体查询器用法总结
    【转】css hack
    【转】移动平台WEB前端开发技巧汇总
    json格式与javascript对象字面量和数组对象的区别
    窗口和元素的大小:offset client scroll
    sharepoint2013 新建母板页 新建页面布局 关联母板页和页面布局
  • 原文地址:https://www.cnblogs.com/logchen/p/10193470.html
Copyright © 2020-2023  润新知