typedef用法总结笔记

本文主要介绍了typedef的多种用法
强调内容使用typedef可以为已由语言定义的类型和对你已经声明的类型构造更段或者更有意义的名称,而且利用typedef封装名称可以减少部分define定义带来的错误。与class, sturct union, enum声明不同, typedef不会引入新类型 -只是引入现有类型的新名称。

使用 typedef声明的名称将占用与其他标识符相同的命名空间(不包括语句标签)。 因此,它们不能使用与前一个声明的名称相同的标识符(除了在类类型声明中.

作用


1. 定义一种类型的别名,这种定义不是简单的替换,而是封装。

例如:char *p1, p2
我们想一次性声明两个char*的指针变量,但是结果却是声明了一个char*指针和一个char字符变量。
使用typedef声明后:

typedef char * PCHAR;
PCHAR p1, p2; //可行,同时声明两个指向字符的指针


2. 同样是定义别名,还可以用来定义与平台无关的类型。

比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

typedef long double REAL;

在不支持 long double 的平台二上,改为:

typedef double REAL;

在连 double 都不支持的平台三上,改为:

typedef float REAL;

也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。
标准库就广泛使用了这个技巧,比如size_t。


3. 在旧的C代码中,使用typedef来声明结构体,能够简化代码。也可以用在声明类类型的别名。

struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
/* C++中,则可以直接写:结构名 对象名,即:tagPOINT1 p1 */
typedef struct tagPOINT
{
int x;
int y;
}POINT;
POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候


4. 为很多复杂的声明定义一个简单的新别名

  • 4.1 定义数组类型
typedef int Array [100]; 
Array ia;//相当于 int ia[100];
  • 4.2 定义函数指针
    函数指针指向的是函数,而非对象,同时与函数类型的决定因素相同,都是由返回类型形参类型共同决定的,和函数名无关
bool lengthCompare(const string &, const string &);
//该函数的类型是bool(const string &, const string &);
bool (*pf) (const string &, const string &);//未初始化
/* *pf两端的括号必不可少,如果不写这两个括号,那么则是声明一个pf的函数,返回值是char *类型,形参是const string &, const string &  */
pf = lengthCompare; //
pf = &lengthCompare;// 以上两条语句都是正确的:取地址符可有可无
/* 此外还可以通过函数指针调用函数,无须解引用指针也可以调用*/
bool b1 = pf("hello", "goodbye");
bool b2 = (*pf)("hello", "goodbye");
bool b3 = lengthCompare("hello", "goodbye"); //以上三条语句都是一样的

和数组类似,虽然不能定义函数类型的形参,但是形参可以是指向函数的指针。此时,形参看起来是函数类型,实际上却是当成指针使用。(函数类型的形参会自动转换为指针

void useBigger(const string &s1, const string &s2, 
                bool pf(const string &, const string &));//看似类型 实则指针
void useBigger(const string &s1, const string &s2, 
                bool (*pf)(const string &, const string &));//等价:显示的声明  
/* 调用时,可直接函数名作为实参使用,自动被转换为指针,或者直接写指针也行 */       
bool (*pf)(const string &, const string &) = lengthCompare;
useBigger(s1, s2, lengthCompare);
useBigger(s1, s2, pf); //pf是指向lengthCompare的函数指针

重点来了!!!!!typedef登场
强调!!!!!decltype只是返回函数类型,不能自动转换为指针的喔,要自己加*

//Func和Fun2函数类型
typedef bool Func(const string &, const string &);
typedef decltype(lengthCompare) Func2; //等价定义
//FuncP和FuncP2都是指向函数的指针
typedef bool (*FuncP)(const string &, const string &);
typedef decltype(lengthCompare) *FuncP2; //等价定义
//使用了类型别名后,的函数声明,和上面部分的是一个作用,大家可以看看哪个更舒服
void useBigger(const string &s1, const string &s2, Func); 
void useBigger(const string &s1, const string &s2, Func2); //同上句
void useBigger(const string &s1, const string &s2, FuncP);
void useBigger(const string &s1, const string &s2, FuncP2);//同上句

和数组类似,不能返回一个函数,那么可以返回一个指向函数的指针。既然用typedef定义的函数指针可以作为形参,那么也是可以作为返回值的

typedef int F(int*, int);
using F1 = int(int*, int);//等价上句
typedef int (*PF)(int*, int);
using PF1 = int(*)(int*, int);//等价上句,不小心就介绍了using的用法
//假设f1(int)是一个形参为int,返回值为一个指向函数(形参为(int*, int),返回值为int*)的指针
PF f1(int);    //正确,PF是指向函数的指针,类型也正是f1所返回的函数的类型
F f1(int);     //错误,F是函数类型,f1不能返回一个函数
F* f1(int);    //正确,显式的指定返回类型是一个指向函数的指针
//当然我们也能用更傻瓜的方式声明这个函数
int (*f1(int))(int*, int);
//当然还可以使用新特性——置尾返回类型
auto f1(int) -> int (*)(int*, int);

目前就考虑到这么多,如果有其他的发现还会补充的。

你可能感兴趣的:(C++)