## 一.類型轉換
+ 類型轉換會生成一個新的匿名對象 ,而不是修改原有的變量。
+ 類類型轉換時,調用類型轉換函數或轉換構造函數。
## 二.隱式類型轉換
### 1.發生的時機
+ 在混合類型的算術表達式中(也叫 **算術轉換** )
```c++
3.14159 + 25;
```
+ 用一種類型的表達式初始化或賦值給另一種類型的對象。
```c++
int a = 3.14159;
```
+ 把一個表達式傳遞給一個函數調用,而表達式的類型與形式參數的類型不相同。
```c++
double MySqrt( double );
MySqrt(2);
```
+ 從一個函數返回一個表達式 表達式的類型與返回類型不相同。
```c++
double fun()
{
return 233;
}
```
### 2.特殊類型的隱式轉換
+ **左值到右值** 任何非函數、非數組類型的左值(新標準為泛左值),可隱式轉換成同類型的右值(新標準為純右值)。
+ **布爾轉換** 在條件或需要 `bool` 的表達式中,整數、浮點、枚舉、指針和成員指針轉換成布爾類型。零值、`NULL` 和 `nullptr` 轉換成 `false` ,其余轉換成 `true` 。
> 需要注意的是,當成員指針為 `NULL` 或 `nullptr` 時,成員指針的值為 `-1` ,但會轉換成 `false`。
+ **數組轉換成指針** 在大多數用到數組的表達式中,數組自動轉換成指向數組首元素的指針。除了 `sizeof` 、 `typeid` 和取地址運算符。
> 需要注意的是,當數組作為函數參數時,編譯器會將其 **替換而不是轉換** 成指針。
+ **函數轉換成指針** 函數作為值使用時,會轉換成指向函數自身的指針。非靜態成員函數除外。
對于函數名(不是函數指針名) `f` ,有以下規律:
```c++
f == &f;/*true,得到的都是函數的地址*/
*f == f;/*true,得到的都是函數的地址*/
*f == &f;/*true,得到的都是函數的地址*/
```
+ **指針轉換**
+ 指向任意非常量的指針可以轉換為 `void*`
+ 指向任意常量的指針可以轉換為 `const void*`
+ 常數 `0(NULL)` 和 `nullptr` 能夠轉換成任意指針類型。
+ 公有繼承中,派生類指針可以轉換成基類指針。
+ **成員指針轉換**
+ 常數 `0(NULL)` 和 `nullptr` 能夠轉換成任意成員指針類型。此時成員指針的值為 `-1` 。
+ 基類的同類型成員指針可以轉換成派生類同類型成員指針。
+ **常量轉換** 允許非常量類型的指針或引用轉換成指向相應的常量類型的指針或引用。
+ **類定義的轉換** 類型轉換函數和轉換構造函數。
## 三.算術轉換
1. 兩個通用的指導原則
+ 為防止精度損失,如果必要的話,類型總是被提升為較寬的類型。
+ 所有含有小于整型的有序類型的算術表達式在計算之前其類型都會被轉換成整型。
2. **整型提升** 在確定共同的目標提升類型之前,編譯器將把小整數類型轉換成整型。
其中, `bool` 、 `char` 、 `signed char` 、 ` unsigned char` 、 ` short` 和 `unsigned short` 等類型,只要它們所有可能的值都能存在 `int` 里,它們就會提升成 `int` 類型;否則提升成 `unsigned int` 型。
>[warning] 下面幾種情況不屬于整數提升:
>+ 把小整數類型和整型轉換成更大的整數類型。如 `short` 或 `int` 轉換成 `long` 不屬于整型提升。
>+ 小整數之間的轉換。如 `char` 轉換成 `short` 不屬于整型提升。
>+ 整型 `int` 與 無符號整型 `unsigned` 的轉換。
3. **浮點提升** `float` 類型可轉換為 `double` 類型。
>[warning] 下面幾種情況不屬于浮點提升:
>
>+ 把小浮點數類型和雙精度浮點型轉換成更大的浮點類型。如 `float` 或 `double` 轉換成 `long double` 不屬于浮點提升。
4. 無符號類型的運算對象:結果依賴機器中各個整數類型的相對大小。
+ 若表達式即有有符號類型,又有無符號類型,且無符號類型 >= 有符號類型,則帶符號的運算對象轉換成無符號類型。
```c++
//當一個無符號數和一個負數相加時,b會轉換成無符號類型(無符號最大值加上這個負數)
unsigned int a = 5;
int b = -6;
cout<<a + b;//輸出值4294967295
```
+ 若表達式即有有符號類型,又有無符號類型,且無符號類型 < 有符號類型,則帶符號的運算對象轉換成無符號類型。若該無符號類型的所有值都能存在于帶符號類型中,則轉換成帶符號類型,否則轉換成無符號類型。
```c++
unsigned int e = 5;
double f = -6;
cout<<e + f;//輸出值-1
```
## 四.強制類型轉換
### (一)舊式的強制類型轉換
```c++
類型(表達式);//函數風格
(類型)表達式;//C風格
```
### [$](二)命名的強制類型轉換
1. 格式
+ **類型** 為轉換的目標類型, **若為引用類型,則返回左值** 。
+ **轉換名稱** `static_cast` `const_cast` `dynamic_cast` `reinterpret_cast` 的一種。
```
轉換名稱<類型>(表達式);
```
2. 靜態轉換 `static_cast`
+ **適用**
+ 有定義不含底層 `const` 的轉換。
+ 不能轉換類類型對象之間、類類型對象與內置類型(除了void類型)的指針。
```c++
double slope = static_cast<double>(2020);
//下面是一個錯誤案例
class A {};
class B {};
A *a;
B *b;
b = static_cast<B*>(a);
```
3. 常量轉換 `const_cast`
+ **適用**
+ 常量指針被轉化成非常量指針,轉換后指針指向原來的變量。
+ 常量引用轉為非常量引用。
+ 添加const屬性
>[danger]常量對象不可以被轉換為非常量對象。
>[danger]試圖通過指針去修改常量的內容會產生未定義的后果。
```c++
int a = 2020;
const int* aptr1 = const_cast<const int*>(&a);
int* aptr2 = const_cast<int*>(aptr1);
```
4. 重解釋轉換 `reinterpret_cast`
+ **適用** 無關類型的轉換,無視大小。如指針轉換成對象,指向不同類類型對象之間的指針。
>[danger]這種轉換灰常危險,請慎用。
```c++
class A {};
class B {};
A *a;
B *b;
b = reinterpret_cast<B*>(a);
```
5. 動態轉換 `dynamic_cast`
+ **適用** 將基類的指針或引用安全地轉換成派生類的指針或引用。
- 閱讀說明
- 1.1 概述
- C++基礎
- 1.2 變量與常量
- 1.2.1 變量
- 1.2.2 字面值常量
- 字符型常量
- 數值型常量
- 1.2.3 cv限定符
- 1.3 作用域
- 1.3.1 標識符
- 1.3.2 *命名空間
- 1.3.3 作用域
- 1.3.4 可見性
- 1.4 數據類型
- 1.4.1 概述
- 1.4.2 處理類型
- 類型別名
- * auto說明符
- * decltype說明符
- 1.4.3 數組
- 1.4.4 指針
- 1.4.5 引用
- 1.5 表達式
- 1.5.1 概述
- 1.5.2 值的類別
- 1.5.3 *初始化
- 1.5.4 運算符
- 算術運算符
- 邏輯和關系運算符
- 賦值運算符
- 遞增遞減運算符
- 成員訪問運算符
- 位運算符
- 其他運算符
- 1.5.5 *常量表達式
- 1.5.6 類型轉換
- 第2章 面向過程編程
- 2.1 流程語句
- 2.1.1 條件語句
- 2.1.2 循環語句
- 2.1.3 跳轉語句
- 2.1.4 *異常處理
- 2.2 函數
- 2.2.1 概述
- 2.2.2 函數參數
- 2.2.3 內置函數
- 2.2.4 函數重載
- 2.2.5 * 匿名函數
- 2.3 存儲和生命期
- 2.3.1 生命周期與存儲區域
- 2.3.2 動態內存
- 2.4 *預處理命令
- 第3章 面向對象編程
- 3.1 概述
- 3.2 類和對象
- 3.3 成員
- 3.3.1 訪問限制
- 3.3.2 常成員
- 3.3.3 靜態成員
- 3.3.4 成員指針
- 3.3.5 this指針
- 3.4 特殊的成員函數
- 3.4.1 概述
- 3.4.2 構造函數
- 3.4.3 析構函數
- 3.4.4 拷貝語義
- 3.4.5 * 移動語義
- 3.5 友元
- 3.6 運算符重載與類型轉換
- 3.6.1 概述
- 3.6.2 重載方法
- 3.6.3 類型轉換
- 3.7 繼承與多態性
- 3.7.1 概述
- 3.7.2 派生類
- 3.7.3 子類型
- 3.7.4 虛基類
- 3.7.5 虛函數
- 3.7.6 抽象類
- 3.8 模板與泛型
- 3.8.1 概述
- 3.8.2 模板類型
- 3.8.3 *模板參數
- 3.8.4 *模板編譯
- 3.8.5 *模板推斷
- 3.8.6 *實例化與特例化
- 第4章 C++標準庫
- 4.1 概述
- 4.2 輸入輸出流
- 4.2.1 概述
- 4.2.2 *流的狀態
- 4.2.3 *常用流
- 4.2.4 *格式化I/O
- 4.2.5 *低級I/O
- 4.2.6 *隨機訪問
- 4.3 *C輸入輸出
- 4.3.1 *字符輸入輸出
- 4.3.2 *格式化輸入輸出
- 4.4 * 容器
- 4.4.1 * 概述
- 4.4.2 * 基本操作
- 4.4.3 * 順序容器
- 4.4.4 * 迭代器
- 4.4.5 * 容器適配器
- 4.5 * 泛型算法
- 4.6 * 內存管理
- 4.6.1 * 自動指針
- 4.7 * 其他設施