一、基本用法:
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>>。