1,類型轉換函數主要功能就是做類型轉換,類型轉換是將一個數據從 A 類型轉換 到 B 類型,有隱式類型轉換和強制類型轉換兩種;
2,再論類型轉換:
1,標准數據類型之間會進行隱式的類型安全轉換;
1,C 語言編譯器只會在標准數據類型之間做轉換,並且 C 編譯器內置了些規則,遵循這些規則標准數據間可以進行隱式類型轉換;
2,轉換規則如下:
1,char( ==> short)==> int ==> unsigned int ==> long ==> unsigned long ==> float ==> double;
2,小類型轉換到大類型是允許的,因為這樣是安全的,且不會有警告;
3,有趣的隱式類型轉換實例分析:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int main() 7 { 8 short s = 'a'; 9 unsigned int ui = 1000; 10 int i = -2000; 11 double d = i; 12 13 cout << "d = " << d << endl; 14 cout << "ui = " << ui << endl; 15 cout << "ui + i = " << ui + i << endl; 16 17 if( (ui + i) > 0 ) // 都轉換為無符號類型,為正; 18 { 19 cout << "Positive" << endl; 20 } 21 else 22 { 23 cout << "Negative" << endl; 24 } 25 26 cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl; // 編譯器將兩個操作數都轉換為 int 類型,編譯器這樣做的原因是因為編譯器認為 4 個字節的運算是最高效的,編譯器自認為安全、高效; 27 28 return 0; 29 }
2,輸出結果:
1 d = -2000 2 ui = 1000 3 ui + i = 4294966296 4 Positive 5 sizeof(s + 'b') = 4
4,寫代碼時要盡量的避免隱式類型轉換;
3,問題:
1,普通類型與類類型之間能否進行類型轉換?類類型之間能否進行類型轉換?
2,普通類型到類類型轉換編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Test 7 { 8 int mValue; 9 public: 10 Test() 11 { 12 mValue = 0; 13 } 14 15 explicit Test(int i) 16 { 17 mValue = i; 18 } 19 20 Test operator + (const Test& p) 21 { 22 Test ret(mValue + p.mValue); 23 24 return ret; 25 } 26 27 int value() 28 { 29 return mValue; 30 } 31 }; 32 33 int main() 34 { 35 Test t; 36 37 t = static_cast<Test>(5); // ==> t = Test(5); 從 C 語言角度,這里將 5 強制類型轉換到 Test 類型,只不是編譯器 在這里做了隱式類型轉換,本質是調用轉換構造函數; 38 39 Test r; 40 41 r = t + static_cast<Test>(10); // ==> r = t + Test(10); 如果工程上這行是手誤,則編譯器並不能發現這樣的低級錯誤; 42 43 cout << r.value() << endl; 44 45 return 0; 46 }
4,再論構造函數:
1,構造函數可以定義不同類型的參數;
2,參數滿足下列條件時稱為轉換構造函數:
1,有且僅有一個參數;
1,這個參數類型只要不是自己當前類型就可以;
2,參數是基本類型;
3,參數是其它類類型;
5,另個一視角,舊式的 C 方式強制類型轉換:
1,代碼示例:
1 int i; 2 Test t; 3 4 i = int(1.5); 5 t = Test(100); // 將整型數 100 強制類型轉換到 Test 類類型,本質是調用構造函數;
6,編譯器的行為:
1,編譯器會盡力嘗試讓源碼通過編譯;
2,編譯器盡力嘗試的結果是隱式類型轉換:
1,隱式類型轉換:
1,會讓程序以意想不到的方式進行工作;
2,是工程中 bug 的重要來源;
3,工程中通過 explicit 關鍵字杜絕編譯器的轉換嘗試;
1,explicit,顯示的;
4,轉換構造函數被 explicti 修飾時只能進行顯示轉換;
1,顯示轉換方式:
1,static_cast<ClassName>(value);
1,這里有調用轉換構造函數;
2,ClassName(value); // C++ 角度是手工調用構造函數;
1,這里有調用轉換構造函數,實質就是調用構造函數;
3,(ClassName)value; // C++ 中不推薦;
1,這里有調用轉換構造函數;
7,小結:
1,轉換構造函數只有一個參數;
2,轉換構造函數的參數類型是其他類型;
3,轉換構造函數在類型轉換時被調用;
1,無論是顯示的還是隱式的,都會被調用;
4,隱式類型轉換是工程中 bug 的重要來源;
5,explicit 關鍵字用於杜絕隱式類型轉換;
1,如果不是故意的,更改;
2,如果想要故意的,手動顯示類型轉換;