大家都知道,在 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; };