# 1.5、类型处理
## 类型别名
C++ 提供两种定义类型别名的方式:`typedef` 和 `using`,其中使用 `using` 定义类型别名为 C++11 标准。
``` c++
typedef type newname;
using newname = type;
```
**define 和 typedef的区别**
`typedef` 和 `#define` 都是替一个对象取一个别名,来增强程序的可读性,但是它们有以下几个区别:
1. 原理不同:`#define` 是 C 中的语法,它是预处理指令在预处理的时候进行 简单的字符串替换,不作任何的正确性的检查,只有在编译期才能发现错误;而 `typedef` 是关键字,在编译的时候处理,所以 `typedef` 是有类型检查的功能,在作用域内给类型定一个别名。
2. 功能不同:`typedef` 用来定义类型的别名;`#define` 不只是可以为类型取别名,还可以定义常量、变量、函数、代码。
3. 作用域不同:`#define` 是没有作用域的;而 `typedef` 是带作用域的。
4. 对指针的操作不同:
``` c++
#define INTP1 int*
typedef int* INTP2;
INTP1 p1, p2; // 宏展开之后编程 int* p1, p2; p1 为指针,p2为整型
INTP2 p3, p4; // p3,p4均为指针
```
## 类型转换
**C 风格的类型转换**:`Type b = (Type)a`,无条件转换。
**C++的四种类型转换**:
* `const_cast`: 去除变量的const属性,`type p = const_cast<type>(q);`;
* `static_cast`:类似于C风格的强制转换,无条件转换,`type p = static_cast<type>(q);`;
* `dynamic_cast`:有条件转换,动态类型转换,运行时类型安全检查,`type p = dynamic_cast<type>(q);`;
* `reinterpret_cast`:仅仅重新解释类型,但没有进行二进制的转换;
**内置类型的值转化**
* 非布尔型到布尔型:只有值为0是为false,其它情况为true;
* 布尔型到其它算术类型:只有值为false的时候为0,其它情况为1;
* 浮点型到整型:结果将被截断,仅保留小数点前的数值;
* 整型到浮点型:小数点后部分为0;
* 赋值一个溢出值给无符号整型:仅保留对应无符号整型可接受的 bit 位;
* 赋值一个溢出值给有符号整型:无定义行为;
## 类型推导
在C++11标准下,可以使用 `auto` 和 `decltype` 两个关键词进行类型的自动推导。
### auto
通过 `auto` 可以让编译器自行计算变量的类型(在编译阶段确定):
``` c++
int i = 0, *p = &i;
auto ai = i; // ai is an int
auto ap = p; // ap is a pointer to int
```
在某些情况下 `auto` 计算的得到的类型不和初始类型保持一致:
1、对于引用对象, `auto` 会识别其对应的类型,而不是该引用。
``` c++
int i = 0, &r = i;
auto a = r; // a is an int (r is an alias for i, which has type int)
```
2、`auto` 通常会忽略 top-level const属性。
``` c++
const int ci = i, &cr = ci;
auto b = ci; // b is an int (top-level const is dropped)
auto c = cr; // c is an int (cr is an alias for ci whose const is top-level)
auto d = &i; // d is an int*
auto e = &ci; // e is const int* (& of a const object is low-level const)
const auto f = ci; // deduced type of ci is int; f has type const int
```
### decltype
`decltype` 支持从表达式中推导类型,并且保留 const 和引用等属性。
``` c++
decltype(f()) sum = x; // sum has whatever type f returns, the compiler does not call f
```
### auto 和 decltype 的区别
* auto 要求变量必须初始化,也就是在定义变量的同时必须给它赋值;而 decltype 不要求,初始化与否都不影响变量的类型;
* decltype 会保留 const 限定符,而 auto 有可能会去掉 const 限定符;
* decltype 会保留引用类型,而 auto 会抛弃引用类型,直接推导出它的原始类型;
- 目录
- 基础知识
- 1、变量和基础类型
- 1.1、内置类型
- 1.2、变量
- 1.3、复合类型
- 1.4、类型修饰符
- 1.5、类型处理
- 1.6、自定义结构
- 1.7、数组
- 2、表达式和语句
- 2.1、运算符
- 2.2、语句
- 3、函数
- 1、语法相关
- 2、资源管理
- 3、面向对象
- 4、模板与泛型编程
- Problem01:判断类中是否包含函数
- Problem02:解析函数的参数类型
- 5、系统库
- Problem01:多线程维护最大值
- Problem02:介绍一下strcpy、strncpy、memcpy、memmove
- Problem03:介绍一下网络编程
- Problem04:select、poll、epoll的区别
- 未整理
- Problem11:实现在main函数前、后执行的函数
- Problem12:可变参函数的实现
- Problem13:全局变量初始化顺序问题
- Problem14:介绍一下隐式转换
- Problem07:实现一个不能被拷贝的类
- Problem08:实现一个只能通过动态、静态分配的类
- 开源项目
- redis
- 第一部分 数据结构与对象
- redis 底层数据结构
- redis 对象
- taskflow
- 数据结构
- Executor
