C風格的強制類型轉換(Type Cast)很簡單,不管什么類型的轉換統統是:
TYPE b = (TYPE)a
C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用。
static_cast 靜態類型轉換。如int轉換成char
reinterpreter_cast 重新解釋類型
dynamic_cast 命名上理解是動態類型轉換。如子類和父類之間的多態類型轉換。
const_cast, 字面上理解就是去const屬性。
4種類型轉換的格式:
TYPE B = static_cast<TYPE> (a)
一般性介紹
1)static_cast<>() 靜態類型轉換,編譯的時c++編譯器會做類型檢查;
基本類型能轉換 但是不能轉換指針類型
2)若不同類型之間,進行強制類型轉換,用reinterpret_cast<>() 進行重新解釋
3)一般性結論:
C語言中 能隱式類型轉換的,在c++中可用 static_cast<>()進行類型轉換。因C++編譯器在編譯檢查一般都能通過;
C語言中不能隱式類型轉換的,在c++中可以用 reinterpret_cast<>() 進行強行類型 解釋。總結:static_cast<>()和reinterpret_cast<>() 基本上把C語言中的 強制類型轉換給覆蓋
reinterpret_cast<>()很難保證移植性。
4)dynamic_cast<>(),動態類型轉換,安全的基類和子類之間轉換;運行時類型檢查
5)const_cast<>(),去除變量的只讀屬性
典型案例
static_cast和reinterpreter_cast
#include <iostream> using namespace std; int main() { double dpi = 3.1415926; int num1 = (int)dpi; // c類型轉換 int num2 = static_cast<int> (dpi); // c++靜態類型轉換, 編譯時編譯器會進行類型檢查 int num3 = dpi; // c語言中,隱士類型轉換的地方,去可以使用,有警告,但是加上Static_cast就沒了 // char* ===> int* char *p1 = "hello world"; int *p2 = NULL; // p2 = static_cast<int*>(p1); // 編譯器會進行類型檢查,有錯就提示出來 p2 = reinterpret_cast<int*> (p1); cout << "p1 = " << p1 <<endl; //%s 一個字符串,如果是*p1就是h cout << "p2 = " << p2 << endl; //%d 字符串的首地址 // 總結:通過reinterpreter_cast<>(),static_cast<>(),把c語言中的強制類型都覆蓋了 return 0; }
//結果
//p1 = hello world
//p2 = 0x47f048
dynamic_cast用法和reinterpret_cast用法
#include <iostream> using namespace std; /* C分格的強制類型轉換(Type cast),很簡單,不管什么類型,都是 Type b = (Type)a; C++風格提供了4種類型轉換操作符,來對應不同的場合的應用 static_cast 靜態類型轉換,如int轉換成char reinterpreter_cast 重新解釋類型 dynamic_cast 命名上理解動態類型轉換,如子類和父類之間的多態類型轉換 const_cast 字面理解就是const屬性 4中類型轉換格式: Type b = static_cast<Type> (a); */ class Animal { public: virtual void cry() = 0; }; class Dog : public Animal { public: virtual void cry() // 虛函數重寫 { cout <<"\t汪汪" << endl; } void doHome() { cout << "\t看家" << endl; } }; class Cat : public Animal { public: virtual void cry() { cout << "\t喵喵" <<endl; } void doThing() { cout << "\t抓老鼠" << endl; } }; // 對象唱戲,發生多態, 只能用指針或者引用 void playObj(Animal &base) { base.cry(); // 1有繼承, 2 虛函數重寫,3父類指針(引用) 指向子類對象 ===> 發生多態 cout << endl; // 需求:識別子類對象 // dynamic_cast 運行時類型識別 Dog *pDog = dynamic_cast<Dog *> (&base); if (pDog != NULL) { pDog->doHome(); // 做自己特有的工作 } cout << endl; Cat *c1 = dynamic_cast<Cat *> (&base); // 父類對象 ==> 子類對象 // 向下轉型 // 把老子轉成小子 if (c1 != NULL) { c1->doThing(); } } class Tree{}; int main() { Dog d1; Cat c1; Animal *pBase = NULL; pBase = &d1; pBase = static_cast<Animal*>(&d1); // c++編譯時,進行類型檢查,將d1指針轉換成父類指針 // 強制類型轉換 pBase = reinterpret_cast<Animal*>(&d1); { Tree t1; // 將樹指針 轉換成動物類指針 // pBase = static_cast<Animal*> (&t1); // c++編譯器,類型檢查 不通過 pBase = reinterpret_cast<Animal*> (&t1); // 可以 重新解釋。。。。強制類型轉換的味道 } playObj(d1); playObj(c1); return 0; }
//結果
// 汪汪
//
// 看家
//
// 喵喵
//
//
// 抓老鼠
const_cast用法
// const char*p,中得const表示 p指向的內存空間 不可以修改 就是*p(值)不能改 void printBuf(const char*p) { // p[0] = 't'; 報錯 char *p1 = NULL; // 程序員要清楚地知道:變量轉換前,和轉換后的類型 p1 = const_cast<char*>(p); // 將p 由const char* == > char* cout << "p = " << p << endl; p1[1] = 't'; // 通過p1修改了 p指向的內存空間 // 轉換后 可以間接修改p的值,不准換的話,也不能間接修改 cout << "p = " << p << endl; } int main() { char buf[] = "aaaaa"; // 程序員 要確保 p所指向的內存空間,確實能修改,如果不能修改,會帶來災難性的后果 printBuf(buf); // char *myBuf = "bbbbbbbb"; // 常量,不能修改 // printBuf(myBuf); return 0; }

