zoukankan      html  css  js  c++  java
  • c++11

    c++的一些资料:

    https://cpp.zeef.com/faraz.fallahi

    语言核心

    一、long long 类型

      int 型最大只能表示21亿多的大小,是不是经常感觉不够用?那么 long long 也许能满足你的需求,LINUX平台下它最大可以表示 9223372036854775807。这里简单提一下获取各个数值类型的方法(不同平台下得出结果可能会不同):

    #include <limits.h>
    #include <iostream>
    
    int main()
    {
        std::cout<<CHAR_MIN<<std::endl;
        std::cout<<CHAR_MAX<<std::endl;
        std::cout<<SHRT_MIN<<std::endl;
        std::cout<<SHRT_MAX<<std::endl;
        std::cout<<INT_MIN<<std::endl;
        std::cout<<INT_MAX<<std::endl;
        std::cout<<LLONG_MIN<<std::endl;
        std::cout<<LLONG_MAX<<std::endl;
    
        std::cout<<UCHAR_MAX<<std::endl;
        std::cout<<USHRT_MAX<<std::endl;
        std::cout<<UINT_MAX<<std::endl;
        std::cout<<ULLONG_MAX<<std::endl;
    }

      我们看到这里引入的头文件实质上是C语言的头文件,LINUX下可能为 /usr/include/limits.h ,这是因为 C 语言早前就已经包含了 long long 类型了,当然你也可以引入c++的头文件 #include <climits> 来达成相同的效果。

     

     

    二、列表初始化

    int array[] = {1,2,3,4,5};

      c++可以像上面那样通过花括号的形式给数组初始化,但是却不能用同样的方式给 vector 初始化。在 c++11 中,这一点得到改善,且可以使用花括号的一致风格为变量或对象进行初始化。

    #include <vector>
    
    class User
    {
        public:
            User(std::string _name):name(_name){}
            std::string name;
    };
    
    int main()
    {
        std::vector<int> vect = {1,2,3,4,5};
        User my = {"yugd"};
    }

     

     

    三、nullptr

      设置空指针有三种方法,置为 0 或 NULL(预处理变量,实质上还是0) 或 nullptr。

      因为 0 存在多义性,比如经典的分别使用指针和数值型重载的函数,当传入0时,就会出现二义性,此时为明确调用指针型的重载,最好传入 (void*)0 ,如果要明确调用INT型的重载,最好传入 int(0)。(如 jsoncpp 库中 Value.h 文件中的 Value &operator[]( const char *key ); 和  Value &operator[]( UInt index ); ) 所以使用 nullptr 会更清晰直观。

     

     

     

    四、enum class

      从字面上可以叫 "枚举类" ,俗称 "强类型枚举" ,英文一般叫 "scoped enums" ,它弥补了一些旧式枚举带来的问题:

    1、旧式枚举可以隐式转换成 int,意味着枚举与 int 值、枚举与枚举之间可以进行比较(而这通常是不合理的)。强类型枚举则需要强制转换成 int 型,增加了类型安全。

    2、旧式枚举因为没有 "界限" 的概念,通过枚举字段直接访问,所以不同枚举不能定义相同名字的枚举字段。在一个大型项目中,这是个比较蛋疼的事。比如这样编译时会报 SUCCESS 重定义:

    enum Buy
    {
        SUCCESS,
        MONEY_NOT_ENOUGH,
    };
    
    enum Sell
    {
        SUCCESS,
        FAILD,
    };

      此时可以使用这样的方法避免该问题:

    #include <iostream>
    
    struct Buy
    {
        enum
        {
            SUCCESS = 1001,
            MONEY_NOT_ENOUGH = 1002,
        };
    };
    
    struct Sell
    {
        enum
        {
            SUCCESS = 2001,
            FAILD = 2002,
        };
    };
    
    int main()
    {
        std::cout<<Buy::SUCCESS<<std::endl;
        std::cout<<Sell::SUCCESS<<std::endl;
    }

      但更好的方法是直接使用 enum class。

    3、enum class 可以为枚举元素指定类型,如果不指定则默认是 int(但依然不能直接隐式转化成 int),如:

    enum class Buy : unsigned int
    {
        SUCCESS,
        MONEY_NOT_ENOUGH,
    };

      此特性使得编译器可以确定枚举参数所占空间的大小,这样 enum class 就可以像普通类一样进行前向声明了,这一点是旧式枚举无法做到的,此特性对于优化大项目的编译时间可能会非常有用。

    五、override 与 final

      新增的继承控制关键字,override 用于修饰子类的成员方法,明确表示此方法重载了基类的相应方法,编译器会检查函数签名是否完全一致,若不一致将报错。可以避免在想要重载时因签名不匹配,导致事实上并非重载的情况。

      final 关键字有两个作用,一是修饰类,禁止该类被继承;二是修饰虚函数(此前只要基类中某成员函数为virtual,则子类重载的函数也自动为virtual函数,即使不用 virtual 修饰,所以只要愿意可以无限重载下去),禁止该虚函数被子类重载。

    运行期表现强化:

    1、右值引用

    构造期表现强化:

    可用性强化:

    功能强化:

     

    库的变更

    一、std::function、std::bind 与 Lambda

    std::function 类似于函数指针,但更为灵活,与之相关的是 std::bind 和 Lambda表达式,这两者返回的都是 std::function 对象,三者联系紧密,示例如下:

    #include <iostream>
    #include <string>
    #include <functional>
    
    int add(int i, int j)
    {
        return i + j;
    }
    
    int sub(int i, int j)
    {
        return i - j;
    }
    
    int main()
    {
        //typedef std::function<int(int,int)> Func; //定义一个该函数对象的类型
        //Func func;    //定义一个该类型的函数对象
        std::function<int(int,int)> func;   //直接定义一个函数对象
    
        func = add;
        std::cout<<func(4,3)<<std::endl;        //7
        func = sub;
        std::cout<<func(4,3)<<std::endl;        //1
    
        //std::bind 返回的就是 std::function 对象,std::bind 中有几个占位符,返回的std::function 函数对象就有几个参数
        std::function<int(int)> func1 = std::bind(sub,4,3);
        std::cout<<func1(5)<<std::endl;         //1
        // std::function 函数对象可以多出无用参数
        std::function<int(int)> func1_ = std::bind(sub,4,3);
        std::cout<<func1_(5)<<std::endl;            //1
        //这一点应用很多,如cocos2d-x中使用std::bind来绑定点击处理函数,应该是传入 std::function<void(Ref*)> ,但实际可以这样写:btn->addClickEventListener(std::bind(&GameLayer::backScene, this));
    
        std::function<int(int)> func2 = std::bind(sub,4,std::placeholders::_1); //sub函数的第二个参数被占位为1号参数
        std::cout<<func2(3)<<std::endl;         //1
    
        std::function<int(int,int)> func3 = std::bind(sub,std::placeholders::_2,std::placeholders::_1); //sub函数第一个参数被占位为2号参数,第二个参数
    被占位为1号参数,所以下面的输出不是 1 而是 -1
        std::cout<<func3(4,3)<<std::endl;       //-1
    
        //Lambda表达式与 std::bind 一样返回的是 std::function 函数对象
        std::function<int(int,int)> func4 = [](int i, int j){return i+j;};
        std::cout<<func4(4,3)<<std::endl;
    }
  • 相关阅读:
    python多线程编程(6): 队列同步
    Python验证Url地址的正则表达式
    centos下redis安全配置相关
    redis
    mysql安装 配置
    centos7安装python3 环境变量配置 django安装 以及tab补全功能
    saltstack 与常用服务部署
    vim
    Linux系统基础优化及常用命令
    Shell 基本命令
  • 原文地址:https://www.cnblogs.com/tianyajuanke/p/3952471.html
Copyright © 2011-2022 走看看