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;
    }
  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/tianyajuanke/p/3952471.html
Copyright © 2011-2022 走看看