zoukankan      html  css  js  c++  java
  • 32.C++-11版本推荐使用using定义别名(替代typedef)

    大家都知道,在 C++中可以通过 typedef 重定义一个类型:

    typedef unsigned int uint_t;

    被重定义的类型并不是一个新的类型,仅仅只是原有的类型取了一个新的名字。

    但是不能用于模版别名,所以C++11版本推荐,通过using来代替typedef

    示例如下所示:

    template<typename T>
    class Test
    {
    public:
        Test()
        {
            std::cout << "A " << typeid(T).name() << std::endl;
        }
    };
    
    template <typename T>
    using Using_T = Test<T>;
    
    //template <typename T>
    //typedef Test<T> Typedef_T;   //取消屏蔽后,这里将报错,不能用于模版别名,提示: a typedef cannot be a template
    
    int main(int argc, char *argv[])
    {
        Test<int> a1;
        Using_T<int> a2;
       // C<int> a3;        //这里会报错
        return 0;
    }

    除此之外,typedef还有个缺点,就是重定义函数指针时,会增加代码的阅读难度

    比如:

    typedef void (Typdf_ii)(int, int);       //声明函数
    typedef void (*PTypdf_ii)(int, int);      //声明函数指针
    typedef void (*PTypdf_iiArr[3])(int, int);   //声明函数指针数组
    对应的using用法则是:
    using Using_ii = void (int, int);    //声明函数指针
    using PUsing_ii = void (*)(int, int);    //声明函数指针
    using PUsing_iiArr = void (*[3])(int, int);    //声明函数指针数组
    可以看到使用using, 通过赋值来定义别名,和我们平时使用变量类似,所以阅读比 typedef 更加清晰
    示例如下所示:
    #include <iostream>
    using namespace std;
     
    typedef void (Typdf_ii)(int, int);       //声明函数
    typedef void (*PTypdf_ii)(int, int);      //声明函数指针
    typedef void (*PTypdf_iiArr[3])(int, int);   //声明函数指针数组
     
    using Using_ii = void (int, int);    //声明函数指针
    using PUsing_ii = void (*)(int, int);    //声明函数指针
    using PUsing_iiArr = void (*[3])(int, int);    //声明函数指针数组
     
    void func1(int i, int j)
    {
        cout<<"func1:"<<i<<","<<j<<endl;
    }
     
    void func2(int i, int j)
    {
        cout<<"func2:"<<i<<","<<j<<endl;
    }
    void func3(int i, int j)
    {
        cout<<"func3:"<<i<<","<<j<<endl;
    }
     
    int main(int argc, char *argv[])
    { 
        PTypdf_iiArr pTypedf={func1,func2,func3};
     
        PUsing_iiArr pUsing={func1,func2,func3};
     
        pTypedf[0](1,2);        //调用func1函数
        pUsing[1](2,3);          //调用func2函数
     
        return 0;
    }
    enum声明示例如下所示:
    typedef enum tag_DateTime {
        DATETIME_YEAR,
        DATETIME_MONTH,
        DATETIME_DAY,
    } Typedf_DATE;
    
    using Using_DATE = enum tag_Date {
        DATE_YEAR,
        DATE_MONTH,
        DATE_DAY,
    };
    
    
    
        cout<<Typedf_DATE::DATETIME_DAY<<endl;
        cout<<Using_DATE::DATE_YEAR<<endl;
    如果不想enum标签,也可以直接写成:
    using Using_DATE = enum {
        DATE_YEAR,
        DATE_MONTH,
        DATE_DAY,
    };
    
    

    类函数指针声明示例如下所示:
    typedef void (A::*PFUN)(int num);  

    等价于:

    using PFUN = void (A::*)(int num);    //表示只能指向A中的函数,num可以不用填,填的好处,能一眼看出该意义

    使用方法(用来工厂初始化内容)

    #define ARRAYSIZE(array)  ((int)(sizeof(array) / sizeof(array[0])))
    
    class A{
        int valueA;
        int valueB;
    public:
        void funcA(int num)
        {
            valueA =num;
            qDebug()<<"funcA"<<num;
        }
        void funcB(int num)
        {
             valueB =num;
             qDebug()<<"funcB"<<num;
        }
        void init();
    };
    
    using PFUN = void (A::*)(int num);      //声明PFUN只能指向A下面的函数
    
    struct tagAInit {
        PFUN    f;
        int    num;
    };
    
    tagAInit g_arr[]={
        {&A::funcA,100},
        {&A::funcB,220},
    };
    
    void A::init()
    {
        int len = ARRAYSIZE(g_arr);
        for(int i = 0; i < len; i++) {
            (this->*g_arr[i].f)(g_arr[i].num);      //循环初始化变量
        }
    
    }

    然后我们只需要调用init()即可:

    A a1;
    a1.init();        //设置valueA=100 valueB=220

    结构体声明示例如下所示:
    typedef struct tagUsb {
        int Mode;
        int Status;
        int Action;
    }USB;

    等价于:

    using USB =  struct tagUsb {
        int Mode;
        int Status;
        int Action;
    };

     如果不想写结构体名称,可以忽略:

    using USB =  struct {
        int Mode;
        int Status;
        int Action;
    };
     
     


  • 相关阅读:
    Apache 安装 静态编译 动态编译
    Vlan 间路由的方法
    一个无限加载瀑布流jquery实现
    用ajax查询天气
    一个简单移动页面ionic打包成app
    时隔一年再读到the star
    轮播图原生js实现和jquery实现和js面向对象方式实现
    js实现一个简单计算器
    纯css3图片旋转展示
    自定义按钮~自适应布局~常见bug
  • 原文地址:https://www.cnblogs.com/lifexy/p/14098103.html
Copyright © 2011-2022 走看看