一、基本用法:

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