一、基本用法:

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>>。