一、基本用法:
1、普通類型
typedef unsigned int UINT;
2、struct
typedef struct {int x; int y;} Point;
或者
typedef struct t_node {
int Value;
struct t_node *next;
} Node;
或者
typedef strcut t_node Node;
struct t_node {
int Value;
Node *next;
};
3、函數指針
typedef void (*FUNCADDR)(int);
4、類類型
typedef class {
private:
int a;
public:
int b;
} MyClass;
二、深入討論:
1、關于const 和指針
typedef char * pstr;
int mystrcmp(pstr, pstr);
這里將帶我們到達第一個 typedef 陷阱。標準函數 strcmp()有兩個‘const char *'類型的參數。因此,它可能會誤導人們象下面這樣聲明 mystrcmp():
int mystrcmp(const pstr, const pstr);
這是錯誤的,按照順序,‘const pstr'被解釋為‘char * const'(一個指向 char 的常量指針),而不是‘const char *'(指向常量 char 的指針)。
這個問題很容易解決:
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 現在是正確的
2、文本替換
typedef 行為有點像 #define 宏,用其實際類型替代同義字。不同點是 typedef 在編譯時被解釋,因此讓編譯器來應付超越預處理器能力的文本替換。
例如:
typedef int (*PF) (const char *, const char *);
如果要使用下列形式的函數聲明,那么上述這個 typedef 是不可或缺的:
PF Register(PF pf);
展示一下如果不用 typedef,我們是如何實現這個聲明的:
int (*Register (int (*pf)(const char *, const char *)))(const char *, const char *);
3、存儲類關鍵字
typedef 就像 auto,extern,mutable,static,和 register 一樣,是一個存儲類關鍵字。
第二個陷阱:
typedef register int FAST_COUNTER; // 錯誤
編譯通不過。問題出在你不能在聲明中有多個存儲類關鍵字。因為符號 typedef 已經占據了存儲類關鍵字的位置,在 typedef 聲明中不能用 register(或任何其它存儲類關鍵字)。
4、定義機器無關的類型
例如,你可以定義一個叫 REAL 的浮點類型,在目標機器上它可以i獲得最高的精度:
typedef long double REAL;
在不支持 long double 的機器上,該 typedef 看起來會是下面這樣:
typedef double REAL;
并且,在連 double 都不支持的機器上,該 typedef 看起來會是這樣:
typedef float REAL;
你不用對源代碼做任何修改,便可以在每一種平臺上編譯這個使用 REAL 類型的應用程序。唯一要改的是 typedef 本身。在大多數情況下,甚至這個微小的變動完全都可以通過奇妙的條件編譯來自動實現。不是嗎? 標準庫廣泛地使用 typedef 來創建這樣的平臺無關類型:size_t,ptrdiff 和 fpos_t 就是其中的例子。此外,象 std::string 和 std::ofstream 這樣的 typedef 還隱藏了長長的,難以理解的模板特化語法,例如:basic_string<char, char_traits<char>,allocator<char>> 和 basic_ofstream<char, char_traits<char>>。