# 类型转换

URL: https://caijiao.org/cpp/basic/cast
Source: docs/cpp/basic/cast.md
Description: 本节将介绍 C++ 中的类型转换，包括隐式转换、显式转换和强制类型转换等方式，帮助你理解如何处理不同类型的转换。

在 C++ 中，类型转换是指将一种数据类型的值转换为另一种数据类型的过程。类型转换分为隐式类型转换和显式类型转换，理解和使用它们能够避免类型不匹配带来的问题。

## 隐式类型转换（自动类型转换）

隐式类型转换是由编译器自动执行的转换，它发生在一个数据类型可以被转换为另一个数据类型时。例如，当一个较小范围的数据类型被赋值给一个较大范围的数据类型时，编译器会自动进行转换。

### 示例

```cpp
int i = 10;
double d = i;  // int 自动转换为 double
````

在上面的示例中，`int` 类型的变量 `i` 被赋值给 `double` 类型的变量 `d`，编译器会自动将 `i` 转换为 `double` 类型。

### 隐式转换规则

* **整数提升**：在表达式中，`char`、`short` 和 `int` 会被自动提升为 `int` 类型。
* **浮点数与整数之间的转换**：当浮点数与整数进行运算时，整数会被自动转换为浮点数。
* **较小类型到较大类型的转换**：如 `int` 转换为 `long` 或 `float` 转换为 `double`。

## 显式类型转换（强制类型转换）

显式类型转换，或称强制类型转换，是通过编程明确地要求将某一数据类型的值转换为另一种数据类型。可以通过静态转换、C 风格转换和强制转换运算符来实现显式类型转换。

### C 风格转换

```cpp
double d = 3.14;
int i = (int)d;  // 使用 C 风格转换将 double 转换为 int
```

这种类型转换使用圆括号进行，通常不推荐使用，因为它的转换规则不明确，容易引发不预期的错误。

### `static_cast` 转换

`static_cast` 是 C++ 推荐的类型转换方式，适用于大多数常见的类型转换，如基本数据类型之间的转换、指针类型转换等。

```cpp
double d = 3.14;
int i = static_cast<int>(d);  // 使用 static_cast 强制转换
```

`static_cast` 提供了更明确的类型转换，能够捕获许多潜在的错误。

### `reinterpret_cast` 转换

`reinterpret_cast` 用于执行非常规类型的转换，通常用于指针或引用的转换。它可以强制将指针或引用转换为其他类型的指针或引用。

```cpp
int* p = nullptr;
char* c = reinterpret_cast<char*>(p);  // 指针类型转换
```

使用 `reinterpret_cast` 时要小心，因为它忽略了类型的内存结构差异，可能导致未定义的行为。

### `const_cast` 转换

`const_cast` 用于去除或添加对象的 `const` 属性。例如，它可以去除 `const` 限定符，允许修改原本为 `const` 的数据。

```cpp
const int x = 10;
int* p = const_cast<int*>(&x);  // 去除 const 限定符
```

注意：修改 `const` 对象是未定义行为，只有在确信原始对象不会改变时才应使用。

## 类型转换的常见错误

* **丢失数据**：转换过程中可能会丢失精度。例如，将浮点数转换为整数时，小数部分会丢失。

  ```cpp
  double pi = 3.14159;
  int x = static_cast<int>(pi);  // x 的值将是 3，丢失了小数部分
  ```

* **类型不匹配**：强制转换可能会导致类型不匹配，尤其是指针和引用的转换时，应格外小心。

## 小结

* **隐式类型转换**：由编译器自动执行，用于较小类型向较大类型的转换。
* **显式类型转换**：通过显式指定转换方式，如 `static_cast`、`reinterpret_cast` 和 `const_cast` 等。
* **C 风格转换**：通过 `(type)` 来实现类型转换，通常不推荐使用。
* **类型转换注意事项**：在进行类型转换时，应当注意数据丢失和类型不匹配的问题。

通过正确使用类型转换，可以避免错误并确保程序的稳定运行。
