# 基础语法 - 类型别名与const ## typedef 使用关键字 typedef 定义类型别名 例如: ``` typedef double wages; // wages 是 double的别名 typedef wages base, *p; // base 是double的别名, p是double *的别名 ``` 含有typedef的声明语句定义的不再是变量,而是类型别名。 ## alias decalration - 'using' c++11 中扩展了using的使用场景 (c++11之前 using用于引入命名空间名字) 使用关键字 using 定义类型别名 ``` using wages = double; // wages 是 double的别名 using base = wages; // base 是 double的别名 using p = wages *; // p 是 double *的别名 using pstring = char *; // pstring 是 char * 的别名 ``` 定义函数指针: ``` typedef void (*FP)(int, const std::string &); using FP = void (*)(int, const std::string &); // 使用using方式更自然,易懂 ``` `using 比 typedef 的适用范围广`, 例如在using 可以在模板别名中使用,但using却不行。 ``` template using Vec = MyVector>; Vec vec; ``` ## 指针、常量与类型别名 如果某个类型别名指代的是复合类型或常量,那么把它用到声明语句里会产生意想不到的后果 例如下面的声明语句用到了类型pstring, 它实际上是类型 `char *` 的别名 ``` using pstring = char *; const pstring cstr = nullptr; // cstr 是 指向字符 的 常量指针 , 所以cstr是常量,不能被修改 const char *c_str; // c_str是 指向常量字符 的 指针, c_str是普通的指针,可以被修改 ``` cstr的定义相当于: `char * const cstr;` ``` char szBuf[1024] = "hello"; cstr = szBuf; // 错误,cstr 是常量,不能被修改 c_str = szBuf; // 正确 ``` 遇到一条使用了类型别名的声明语句时,人们往往会错误的尝试把类型别名替换成它原本的样子,通过上述的例子可以看到,这种理解是错误的。 简单替换的结果是 `const char` 成了基本数据类型,这两种声明的含义是截然不同的。 ``` const pstring *ps; // ps是一个指针,它的对象是一个指向char的常量指针。ps相当于 `char* const * ps` //ps = &c_str; // 这种写法不正确, &c_str的类型是 const char**, 与ps的类型不匹配 ps = const_cast(&c_str); ```