zoukankan      html  css  js  c++  java
  • 第十章 C++11新特性

    统一的初始化方法

    1. 通过花括号实现各类变量初始化(允许花括号嵌套)

      int arr[3]{1,2,3};
      vector<int> iv{1,2,3};
      map<int,string> mp{{1,"hello"},{2,"world"}};
      int *p=new int[20]{1,2,3}; //前三个变量初始化为1,2,3,其余用默认构造函数初始化
      struct A{int i,j; A(int m,int n):i(m),j(n){}}
      A func(int m,int n){return {m,n};}
      A* pa=new A{2,3};
      

    成员变量可以赋予默认初始值

    1. 示例
      class A{
          public:
          i=5;
      }
      

    auto自动类型关键字

    1. 定义变量时,通过所赋予的值在编译时自动判断变量类型

    2. 可用于模板返回值,提升模板灵活性

      template<class T1,class T2>
      auto Func(T1 x,T2 y)->decltype(x+y){
          return x+y;
      } //auto可以不为T1、T2中的一种,->decltype(x+y)返回值类型声明也可省略
      

    decltype关键字

    1. 用于获取变量或表达式返回值类型

    2. 双括号返回相应类型的引用

      int i;
      decltype(i) x=5;
      decltype((i+x)) y=x;
      

    基于范围的for循环

    1. 格式:for(元素类型 i:数组等名)

    2. 获取时元素,而非指针

      int ary[]{1,2,3,4,5};
      for(int &e:ary) e*=2;
      for(int e:ary) cout<<e<<endl; //2,4,6,8,10
      map<int,string> mp{{1,"A"},{2,"B"}};
      for(auto &e:mp) cout<<e.first<<" "<<e.second<<endl; 
      

    智能指针shared_ptr

    1. 需要头文件<memory>

    2. 写法:shared_ptr ptr(new T);

    3. 自动托管指针,程序结束或托管数为0时自动释放new动态分配的内存

    4. 多个shared_ptr对象可以同时托管一个指针,系统会维护一个托管计数

    5. 不能用于托管指向动态分配的数组

    6. 创建后的指针用法与一般指针相同

      int *p=new int,*p2=new int{1};
      shared_ptr<int> sp1(p);
      shared_ptr<int> sp2(sp1);
      sp2.reset(); //清空sp2
      sp2.reset(p2); //会置托管计数为1,只能用于智能指针第一次指向p2区域。否则可能出错(delete多次)
      sp2=sp1; p2=sp1.get(); //get函数获取地址
      

    空指针nullptr

    1. 与NULL和0的区别:包含类型,能够转换位bool型,却不能转化为整型

    2. 可以直接和NULL和nullptr比较

    3. 不同类型的指针不能比较(如double*和int* 型)

      int *p1==NULL,*p2=nullptr;
      shared_ptr<double> p3=nullptr;
      if(p1==p2) cout<<"Equal
      "; //相等
      if(p3==NULL) cout<<"Equal
      "; //相等
      if(p3==nullptr) cout<<"Equal
      "; //相等
      bool b=nullptr; //b=false
      int i=nullptr; //错误❌
      

    无序容器(哈希表)

    1. unordered_map
    2. 使用与map类似
    3. 插入、查找元素的时间复杂度几乎为常数,但空间占用较多

    Lambda表达式

    1. [外部变量范围方式说明符](形参表)->返回值类型{ 语句组 }
      "->返回值类型"也可以没有,由编译器自动判断

      外部变量访问符 含义
      [] 不使用任何外部变量
      [=] 以传值方式使用外部变量
      [&] 以引用方式使用外部变量
      [x,&y] 传值方式使用x,引用方式使用y
      [=,&x,&y] 引用方式使用x,y,传值方式使用其他变量
      [&,x,y] 传值方式使用x和y,引用方式使用其他变量
    2. 示例

      cout<<[](double x,double y){return x+y;}(1.1,2.2)<<endl; //3.3
      int x=100,y=200;
      auto ff=[&x,&y](int n){
          x++;y++;
          return n*n;
      }
      cout<<ff(15)<<" "<<x<<" "<<y<<endl; //225 101 201
      function<int(int)> fib=[&fib](int n){return n<=2?1:fib(n-1)+fib(n-2);} 
      //无法由返回值确定返回类型,不能用auto。第一个int代表返回值,第二个int代表函数形参表
      cout<<fib(5)<<endl;
      sort(arr,arr+5,[](int a,int b){return a<b;});
      

    右值引用T&&和move移动语义

    1. 详见 参考资料

    2. C++中所有的值都必然属于左值、右值二者之一。左值是指表达式结束后依然存在的持久化对象,右值是指表达式结束时就不再存在的临时对象。所有的具名变量或者对象都是左值,而右值不具名。很难得到左值和右值的真正定义,但是有一个可以区分左值和右值的便捷方法:看能不能对表达式取地址,如果能,则为左值,否则为右值

    3. 目的:提高程序运行效率,减少需要深拷贝的对象的深拷贝次数(通过直接夺取变量已分配动态分配空间)

    4. 具体类型
      左值引用, 使用 T&, 只能绑定左值

      右值引用, 使用 T&&, 只能绑定右值

      常量左值, 使用 const T&, 既可以绑定左值又可以绑定右值

      已命名的右值引用,编译器会认为是个左值

      编译器有返回值优化,但不要过于依赖

    5. 移动构造函数 和移动赋值函数,如String(String&& str)String& operator= (String&& str)

    6. std::move()用于告诉编译器尽量将该变量当成右值处理,不存在移动拷贝、移动赋值时再考虑普通方式

    7. Dev C++中,return局部对象,对导致优化,不调用移动或复制构造函数

    8. 可移动但不可复制的对象:

      struct A{
          A(const A& a)=delete;
          A(const A&& a){cout<<"Move Constructor."<<endl;}
          A(){}
      }
      

    正则表达式

    1. 需包含<regex>头文件

    2. 示例:

      regex reg("\d{3}{[a-zA-Z]+}.(\d{3}|N/A)\s\1"); //在C/C++中反斜杠必须写2个以反义
      cout<<regex_match("123Hello N/A Hello",reg)<<endl; //输出1,匹配成功
      string s("123Hello N/A hello");
      cout<<regex_match(s,reg)<<endl; //输出0
      

    强制类型转换

    1. static_cast
      • 用于比较“自然”和低风险类型的转换,如整型与字符型、浮点型的转换
      • 不能用于不同类型指针、引用转换,或整型与指针的转换
    2. reinterpret_cast
      • 用于不同类型指针、引用的转换,以及指针和能容纳下指针的整数类型的转换,执行逐个比特拷贝的操作
      • 不进行类型检查
    3. const_cast
      • 用来去除const属性,将const指针、引用转为同类型非const类型引用
    4. dynamic_cast
      • 专门用于将多态基类指针或引用转换成派生类指针、引用。
      • 对于不安全的指针转换(指针不是指向派生类对象),转换结果等于NULL
      • 对于不安全的引用转换,抛出bad_cast异常

    异常处理

    1. try中进行可能异常的操作,将异常传递给catch

    2. throw主动抛出异常

    3. catch捕获try传递的异常,可以存在多个catch函数,从上到下对异常进行类型匹配,catch(...)表示匹配任意类型

    4. 发生异常后,try范围内后续命令不再执行,直到异常被捕获

    5. 如果异常未在函数内部处理,就会被抛给上一级的函数

    6. 常见的异常类(从exception类派生而来,位于<stdexcept>中,类型异常位<typeinfo>

      1. out_of_range 如vector、string用at函数范围越界时
      2. bad_alloc 动态分配内存请求失败(typeinfo头文件中)
      3. bad_cast 用dynamic转换基类引用失败(typeinfo头文件中)

      --> 通过异常对象的what()函数获取异常信息

    运行时类型检查

    1. 需要<typeinfo>头文件

    2. 对于多态类,会返回实际指向的对象类型

    3. 示例

      long n;
      cout<<typeid(n).name()<<endl;
      
  • 相关阅读:
    UINavigationController详解
    iOS学习之UINavigationController详解与使用
    UIViewController 之LoadView详解
    UIView详解
    iOS UITableView代理方法详解
    iOS中表视图(UITableView)使用详解
    Objective-C葵花宝典第一重(内功篇)--类与对象
    关于UIScrollView事件
    iOS学习--UIScrollView 原理详解
    ios UIView
  • 原文地址:https://www.cnblogs.com/DreamEagle/p/12632113.html
Copyright © 2011-2022 走看看