C++那些細節--typedef關鍵字
一.簡介
關於typedef關鍵字,以前剛剛學C語言的時候,用它來重定義結構體別名。之後的話就是在用函數指針的時候用過一些,然而並不知道這個還有什麼用處。今天花點時間總結一下typedef的細節。
在計算機編程語言中用來為復雜的聲明定義簡單的別名,與宏定義有些差異。簡單來說,就是用來給一個復雜變量定義一個好記一點的名字。另外,使用typedef可以簡化一些復雜的聲明。
二.typedef的用途
1.定義類型別名,而不是簡單的替換
typedef的第一個功能是定義類型的別名,比如Int*,比較麻煩,我們可以直接定義成pINt代表int型指針。而這種typedef
// C++Test.cpp : 定義控制台應用程序的入口點。
//
#include stdafx.h
#include
using namespace std;
//typedef與#define的區別:
typedef int* TPINT;
#define DPINT int*
int _tmain(int argc, _TCHAR* argv[])
{
int a = 1, b = 2;
//使用typedef的TPINT,兩個都是指針
TPINT tpa, tpb;
tpa = &a;
tpb = &b;
cout<結果:
a by pointer: 1 b by pointer: 2
a by pointer: 1b by value: 2
請按任意鍵繼續. . .
這裡,使用typedef的話,所有定義的TPINT都是int*類型的,而#define僅僅是在編譯的時候,將DPINT替換成了int*,後面的變量dpb就變成了int類型!!!所以,還是typedef靠譜一點!
2.定義平台無關類型
我們知道,編譯宏可以很好的控制編譯流,我們在編譯跨平台程序的時候,很多時候是靠編譯流的。編譯流一般都是一些宏定義來控制。其他功能免不了用#define,但是類型定義有更好的typedef,所以關於類型的定義,我們完全可以使用typedef來替換#define
比如,在一些機器上,int為16位,long為32位,那麼我們可以這樣定義:typedef int INT16
typedef long INT32
但是,有的機器上變成short位16位,int 32位,long變成了64位,那麼我們如果想要運行的話,只能用short和int了,而我們使用了typedef,就可以很輕易的改typedef,而完全不需要大改項目:
typedef short INT16
typedef int INT32
3.為復雜聲明定義一個簡單的別名
typedef可以為復雜聲明定義一個簡單的別名,比如: 我們要定義一個裝著MyObj對象的list,那麼,每次定義的時候都要寫出:
std::list objList;
但是,如果有typedef的話,就可以省去不少麻煩:
typedef std::list ObjList;
ObjList objlist;
不過,最明顯的還是在用函數指針的時候。看一個例子: 不用typedef時,定義函數指針是介個樣子滴:
// C++Test.cpp : 定義控制台應用程序的入口點。
//
#include stdafx.h
#include
using namespace std;
//函數
void testfunc(int x)
{
cout<這個函數目前只有一個參數,看起來都夠麻煩了,那麼如果有一大堆的參數,簡直不忍直視!!!
而typedef閃亮登場之後:// C++Test.cpp : 定義控制台應用程序的入口點。
//
#include stdafx.h
#include
using namespace std;
//函數
void testfunc(int x)
{
cout<結果:
x = 1
x = 2
請按任意鍵繼續. . .
有了typedef,定義一個函數指針就像定義一個Int變量那樣簡單粗暴!!!4.輔助聲明結構體
這個在C++中是不需要的,而且貌似C語言也不需要了。老版本的C編譯器可能會需要使用typedef來輔助定義結構體。typedef struct tpoint
{
int x;
int y;
}Point;
Point pt;
三.typedef的注意事項
1.typedef重新定義類型別名,而非簡單替換
看一個例子,關於const的。
// ConsoleApplication3.cpp : 定義控制台應用程序的入口點。
//
#include stdafx.h
#include
#define DPINT int*
typedef int* PINT;
int _tmain(int argc, _TCHAR* argv[])
{
int i1 = 2;
int i2 = 3;
const PINT pi1 = &i1;
const PINT pi2 = &i2;
const DPINT pi3 = &i1;
//pi1 = &i2;這句是錯誤的,因為pi1整體為一個數據類型,Int*,即指針本身為const。
//而指針指向的內容卻是可變的
*pi1 += 3;
//對於pi3,為單純的替換,即const int* pi3,此處const為底層const,修飾int*所指向的內容。所以指針本身是可以修改指向的
pi3 = &i2;
system(pause);
return 0;
}
還是使用#define和typedef作對比。使用const PINT時,表示的是類型本身是const,而與類型的指向沒關系,類型指向仍然是可變的。這點與#define正好不同!!
2.不能與存儲類型關鍵字同時使用
typedef在語法上是一個存儲類的關鍵字(如auto、extern、mutable、static、register等一樣),雖然它並不真正影響對象的存儲特性。
比如我們將typedef和static一起定義的話: 
就會出現錯誤。