• C++11新标准



    author: lunar
    date: Wed 23 Sep 2020 09:20:09 PM CST

    探讨 C++ 新标准

    《C++ Primer Plus》读书笔记

    本章介绍C++11对C++所做的改进,包括以下主题:

    • 新的声明方式
    • 移动语义和右值引用
    • 新的类功能
    • Lambda 表达式
    • 包装器模板 function
    • 可变参数模板

    新声明

    1. auto

      C++11以后可以将auto用于自动类型推导,大大简化了代码

    2. decltype

      decltype将变量的类型声明为表达式指定的类型。

      decltype(x) y;

      上面的语句意思是让 y 与 x 的类型相同。

      这在定义模板时特别有用

      template<typename T, typename U>
      void func(T t, U u) {
          decltype(T*U) temp;
      }
      
    3. 返回类型后置

      C++11新增了一种语法,允许在函数名和参数列表之后指定返回类型。

      使得你能够使用decltype来指定模板函数的返回类型:

      template<typename T, typename U>
      auto func(T t, U u) -> decltype(T*U) {
          ...
      }
      
    4. 模板别名:using=

      主要用于创建模板的别名。

      template<typename T>
      using arr = std::array<T,12>;
      arr<double> a1;
      

      typedef无法实现这种程度的别名。

    5. nullptr

      以前是使用整数0来表示空指针。

    右值引用与移动语义

    可以参照这篇文章

    新的类功能

    特殊的成员函数

    在原有4个特殊成员函数的基础上,又新增了:移动构造函数和移动赋值运算符。

    默认的方法和禁用的方法

    假定你要使用某个默认的函数,而这个函数由于某种原因不会自动的创建。例如自己写了移动构造函数,编译器就不会自动创建默认的构造函数。

    为此,你可以使用default关键字显式地声明这些函数的默认版本:

    另一方面,通过关键字delete可以禁止编译器使用特定方法。

    使用方法为:

    Someclass() = default;
    Someclass(const Someclass&) = delete;
    

    委托构造函数

    允许在一个构造函数的定义中使用另一个构造函数。

    Inherite constructors

    C++11允许在子类中使用using Base::func;使用父类的函数,包括所有名为func的函数。并且这些函数中如果有在子类中被重新定义的话,会被重载。

    更神奇的是,构造函数也可以使用这种方法进行被子类使用。

    Manage virtual methods:override & final

    使用虚函数的一个缺点就是在子类中的同名函数会覆盖父类的版本,无法进行重载。

    为此,在C++11中可以将override关键字添加到参数列表之后,表示要重载父类的函数。

    同样,如果想要在父类想要禁止派生类中覆盖某个方法,可以在参数列表后面加上final关键字表示禁止重载。(越来越Java化了)

    Lambda 函數

    比較函數指針、函数符和Lambda函数

    C++11引入了Lambda匿名函数,语法格式为

    [](type x) {return expression;}
    

    这是只有一条返回语句的形式。当函数体不止这一条语句时,需要指定返回类型,使用后置返回类型的形式:

    [](type x)->type{body;return expression;}
    

    包装器

    通过标准库中的function对象可以将可调用对象包装,返回一个统一的对象。

    语法格式为

    std::function<func(type x,type y)> func_instance;
    

    随后便可以像函数一样调用。

    可变参数模板

    可变参数模板(variadic tempalte)使得你可创建可接受可变数量的参数的模板函数和模板类。

    语法格式为:

    template<typename... Args>
    void func(Args... args) {
        
    }
    

    Args允许接受大于等于零数量的任意类型的参数。

    问题是我们不能通过索引直接将参数直接取出来。正确的方法是使用递归(真不懂为什么设计成这样),比如下面这种方法:

    //零参数的同名函数用于终止递归
    void func() {
        //do something
    }
    
    //被调用的函数
    template<typename T, typename... Args>
    void func(T t, Args... args) {
        //do something,t可以表示在当前递归里args的第一个参数
        func(args); //在这里递归调用
    }
    
    //如果想要在只剩下一项参数时,还可以定义这样一个函数
    template<typename T>
    void func(T t) {
        //do something
    }
    
    我愿潇洒如鹰,远离地上宿命
  • 相关阅读:
    算法导论(1)堆排序
    Opencv--HoughCircles源码剖析
    数据结构算法应用C++语言描述——(1)C++基础知识
    Java编程的23种设计模式
    团队建设
    管理方法论和角色认知
    压力测试:怎样设计全链路压力测试平台
    09-数据库优化方案(二):写入数据量增加时,如何实现分库分表
    08-数据库优化方案(一):查询请求增加时,如何做主从分离
    07-池化技术:如何减少频繁创建数据库连接的性能损耗
  • 原文地址:https://www.cnblogs.com/lunar-ubuntu/p/13730134.html
Copyright © 2020-2023  润新知