大家都知道,在 C++中可以通過 typedef 重定義一個類型:
大家都知道,在 C++中可以通過 typedef 重定義一個類型:
被重定義的類型并不是一個新的類型,僅僅隻是原有的類型取了一個新的名字。
但是不能用于模版别名,是以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;
};