當一個是無符號類型,另一個是帶符號類型:
若是無符號不小於帶符號,那麼帶符號轉換成無符號。
若是無符號小於帶符號,當無符號類型的全部值都能存到帶符號中時,則無符號轉換成帶符號,不然,
帶符號類型轉換成無符號類型。
好比:
有兩個類型分別是 long 和 unsigned int,若是大小相同,long類型轉換成unsigned int,不然unsigned轉換成long類型ios
數組轉換成指針:
decltype,取地址&,sizeof以及typeid(未知)不會轉換
若是用一個引用初始化數組也不會發生轉換。(引用初始化數組?)c++
類類型定義的轉換:程序員
string s; while(cin >> s) //IO庫定義了從istream向bool的轉換規則,取決因而否讀入成功 { }
cast-name
主要在如下幾種場合中使用:
1.用於類層次結構中,基類和子類之間指針和引用的轉換;
當進行上行轉換,也就是把子類的指針或引用轉換成父類表示,這種轉換是安全的;
當進行下行轉換,也就是把父類的指針或引用轉換成子類表示,這種轉換是不安全的,也須要程序員來保證;
2.用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum等等,這種轉換的安全性須要程序員來保證;
3.把void指針轉換成目標類型的指針,是及其不安全的;
注:static_cast不能轉換掉expression的const、volatile和__unaligned屬性。
參考連接數組
int a = 100; double t = static_cast<double>(a) / 6; cout << t << endl; //16.6667
向上轉換(好像並非確定安全的記住原始的指針類型 ?):安全
class Base1{ //int a; }; class Base2{ public: int b; }; class Derived: public Base1, public Base2{ }; int main() { int a; void *p; Derived pd; pd.b = 10; cout << pd.b <<endl; cout << "pb: " << &pd<< endl; Base2* pb1 = static_cast<Base2 *>(&pd); cout << pb1->b <<endl; cout << "Derived to Base2: " << pb1 << endl; return 0; } 10 pb: 0x68fefc 10 Derived to Base2: 0x68fefc
使用const_cast去除const限定的目的不是爲了修改它的內容,一般是爲了函數可以接受這個實際參數ide
const char *cp; char *p = const_cast<char*>(cp);//經過p寫值是未定義行爲 char *p = static_cast<char*>(cp);//error static_cast<string>(cp); //yes,字符串字面值轉變成string(未實踐) const int a = 100; int *pA = const_cast<int *>(&a); *pA = 200; int &refA = const_cast<int &>(a); refA = 300; // int *pA1 = static_cast<int *>(&a); Error cout << "*pA:" << *pA << endl;//300 cout << "refA:" << refA << endl;//300 cout << "a:" << a << endl;//100 system("pause");
下面是網上摘錄的一段解釋:(or常量摺疊解釋)
const只是告訴編譯器不能修改而不是真正地不可修改,若是程序員不注意而去修改了它會報錯,如今咱們利用const_cast去除了常量性,而後經過指針和引用對其進行了修改,因此經過指針打印或者引用傳參的時候就能看出其內存確實變化了,但爲了保護val這個變量原本的const特性,因此每次咱們使用val時,系統都將其替換成初始值100,確保了val仍是「不可變」的
參考博客函數
#include <iostream> using namespace std; void f(int* p) { cout << *p << endl; } int main(void) { const int a = 10; const int* b = &a; // Function f() expects int*, not const int* // f(b); int* c = const_cast<int*>(b); f(c); // Lvalue is const // *b = 20; // Undefined behavior // *c = 30; int a1 = 40; const int* b1 = &a1; int* c1 = const_cast<int*>(b1); // Integer a1, the object referred to by c1, has // not been declared const *c1 = 50; return 0; } http://www.ibm.com/support/knowledgecenter/SS3KZ4_9.0.0/com.ibm.xlcpp9.bg.doc/language_ref/keyword_const_cast.htm
在函數重載上面的應用:spa
const string &shorterString(const string& a, const string& b) { return a.size() <= b.size() ? a : b; } string &shorterString(string& a, string& b) { auto &r = shorterString(const_cast<const string&>(a), const_cast<const string&>(b)); return const_cast<string &>(r); }
能夠進行任意之間的轉換,不會報錯,可是可能破壞程序.net
int *ip; char *pc = reinterpret<char*>(ip); string str(pc); //pc所指真實對象是一個int,因此有問題 與舊式轉換相似的功能 int *op; char *p = (char*)op; MSDN上的一個應用- - ,不是很懂reinteroret_cast有什麼用 #include <iostream> using namespace std; // Returns a hash code based on an address unsigned short Hash( void *p ) { unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } using namespace std; int main() { int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; }
(想使用基類指針或者引用執行某個派生類非虛函數操做)
dynamic_cast是動態轉換,只有在基類指針轉換爲子類指針時纔有意義。(子類指針轉換爲基類指針原本就是能夠的:基類指針指向子類對象OK)。
可是基類指針轉換爲子類指針,並非每一次都有效:只有基類指針自己指向的是一個派生類的對象,
安全性:
這須要從它的返回值進行討論,若是符合繼承體系且原始指針是指向派生類的對象的,那麼返回值將是一個正確的指針值,不然會返回NULL。因此,咱們能夠對返回值進行判斷來進行判定到底轉換是否正確,從而保證程序的健壯性
必須是一個帶有虛函數的類。由於dynamic_cast是在對象的內存模型中保存了offset值來實現轉換的,這些offset值是保存在虛表(vtbl)中的
虛表參考<Inside c++ object model>:
class MyCompany { public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) { Programmer *pm = dynamic_cast<Programmer *>(pe); //若是pe實際指向一個Programmer對象,dynamic_cast成功,而且開始指向Programmer對象起始處 if(pm) { //call Programmer::bonus() } //若是pe不是實際指向Programmer對象,dynamic_cast失敗,而且pm = 0 else { //use Employee member functions } } class A { public: virtual ~A(){} //虛函數 多態 }; class B:public A { public: int m; }; A* pObjA = new A(); B* pObjB = NULL; pObjB = dynamic_cast<B*>(pObjA); //編譯經過 //實際運行結果:pObjB == NULL // dynamic_cast保證轉換無效 返回NULL
來自爲知筆記(Wiz)