# static_cast 等

URL: https://caijiao.org/cpp/oop/cast
Source: docs/cpp/oop/cast.md
Description: 本节讲解 'static_cast' 和其他类型转换操作符（如 'reinterpret_cast'、'const_cast'），分析它们的使用场景和区别。

在 C++ 中，类型转换操作符用于在不同类型之间进行转换。C++ 提供了多种类型转换操作符，每种操作符都有不同的用途和限制。常用的类型转换操作符包括 `static_cast`、`dynamic_cast`、`const_cast` 和 `reinterpret_cast`。本节将重点讲解 `static_cast` 和其他类型转换操作符的使用场景与区别。

## `static_cast`：常规的类型转换

`static_cast` 是最常用的类型转换操作符之一，它用于在类型之间进行编译时类型转换。`static_cast` 可以用于大多数常见的类型转换，如基本类型之间的转换、指针和引用类型之间的转换，以及类层次结构中的类型转换。

### 使用 `static_cast`

`static_cast` 适用于静态转换，通常用于已知类型之间的转换，且不涉及运行时检查。例如，它可以用于将 `int` 转换为 `float`，将基类指针转换为派生类指针等。

### 示例：使用 `static_cast`

```cpp
#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() { cout << "Base class" << endl; }
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void show() override { cout << "Derived class" << endl; }
};

int main() {
    Base* base = new Derived();

    // 使用 static_cast 进行类型转换
    Derived* derived = static_cast<Derived*>(base);
    derived->show();  // 输出 Derived class

    delete base;
    return 0;
}
````

### 输出：

```
Derived class
```

### 解释

* `static_cast` 用于将基类指针 `base` 转换为派生类指针 `derived`。由于 `base` 实际指向一个 `Derived` 对象，转换是安全的。
* 注意，`static_cast` 仅适用于类型之间的转换，并不会检查类型转换是否有效。如果 `base` 指向的是其他类型的对象，使用 `static_cast` 可能会导致未定义行为。

## `dynamic_cast`：运行时类型检查

`dynamic_cast` 主要用于多态类型的转换，特别是涉及类的继承关系时。与 `static_cast` 不同，`dynamic_cast` 会在运行时进行类型检查，确保类型转换的安全性。如果转换失败，`dynamic_cast` 会返回 `nullptr`（对于指针类型）或抛出 `std::bad_cast` 异常（对于引用类型）。

### 示例：使用 `dynamic_cast`

```cpp
#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() { cout << "Base class" << endl; }
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void show() override { cout << "Derived class" << endl; }
};

int main() {
    Base* base = new Derived();

    // 使用 dynamic_cast 进行安全转换
    Derived* derived = dynamic_cast<Derived*>(base);
    if (derived) {
        derived->show();  // 输出 Derived class
    } else {
        cout << "Conversion failed!" << endl;
    }

    delete base;
    return 0;
}
```

### 输出：

```
Derived class
```

## `const_cast`：修改常量性

`const_cast` 用于在常量对象和非常量对象之间进行转换。它可以添加或删除常量性，即将常量指针转换为非常量指针，或将非常量指针转换为常量指针。`const_cast` 并不会改变对象本身的内容，它仅仅改变了指针或引用的常量性。

### 示例：使用 `const_cast`

```cpp
#include <iostream>
using namespace std;

void printMessage(const string& message) {
    // 使用 const_cast 去除常量性
    string& modifiableMessage = const_cast<string&>(message);
    modifiableMessage = "Modified message";  // 可以修改消息内容

    cout << modifiableMessage << endl;
}

int main() {
    const string msg = "Original message";
    printMessage(msg);  // 输出 Modified message
    return 0;
}
```

### 输出：

```
Modified message
```

### 解释

* `const_cast` 用于去除常量性，使得原本是 `const` 的变量可以被修改。在此示例中，我们通过 `const_cast` 去除常量性，从而修改了 `message` 的值。

## `reinterpret_cast`：强制类型转换

`reinterpret_cast` 是一种较为危险的类型转换操作符，它可以将任何类型的指针转换为任何其他类型的指针。通常情况下，`reinterpret_cast` 会绕过类型系统，直接进行内存级别的转换。它的使用必须小心，因为错误的使用可能导致程序崩溃或未定义行为。

### 示例：使用 `reinterpret_cast`

```cpp
#include <iostream>
using namespace std;

int main() {
    int num = 65;
    char* ptr = reinterpret_cast<char*>(&num);

    cout << *ptr << endl;  // 输出 A (65 对应字符 A)

    return 0;
}
```

### 输出：

```
A
```

### 解释

* `reinterpret_cast` 将 `int` 类型的指针转换为 `char` 类型的指针。这种转换改变了指针的底层数据解释，因此我们可以将整数值 `65` 作为字符输出。

## 小结

* **`static_cast`**：用于常规的类型转换，适用于类型之间的编译时转换，如基本类型的转换、指针类型的转换等。
* **`dynamic_cast`**：用于多态类型的安全转换，确保在运行时类型转换的安全性，适用于类的继承关系。
* **`const_cast`**：用于修改常量性的转换，可以去除常量性或添加常量性。
* **`reinterpret_cast`**：用于强制类型转换，通常在底层操作中使用，能够绕过类型系统，直接进行内存级别的转换。

选择合适的类型转换操作符可以提高程序的类型安全性，避免潜在的错误和不安全操作。
