c++有著豐富的資料型別(11種整型和3種浮點型),相同型別間運算的硬體指令可能會與其他型別間的不同。為了處理這種潛在的混亂,c++中存在了很多隱式型別轉換
(1)基礎型別
short a=2000;
int b;
b=a; //將一種算術型別的值賦給另一種算術型別的變數
這裡無需任何顯式操作,c++將short值轉換為int,這種轉換被稱為整型提公升(integral promotion);
之所以稱為提公升,因其可以保證目標型別中會產生完全相同的值。當然基礎型別之前的其他轉換可能不能夠精確地表達相同的值:
一般高位元組型別向低位元組型別轉換意味著精度的損失,編譯器會發出警告。當然可以通過顯示轉換來避免此警告~
各基礎型別大小
char
short
intlong
float
double
指標32位編譯器12
4448
464位編譯器12
4848
8(2)非基礎型別
對於非基礎型別,陣列和函式隱式轉換為指標,並且指標通常允許以下轉換:
在類的世界裡是通過三個成員函式來控制隱式轉換的:
例如:
// implicit conversion of classes:
#include using namespace std;
class a {};
class b
// conversion from a (assignment):
b& operator= (const a& x)
// conversion to a (type-cast operator)
operator a()
};int main ()
(1)explicit
關鍵字
在函式呼叫中,c ++允許對每個引數進行一次隱式轉換。對於類來說,這可能會有些問題,因為它並不總是預期的。例如,如果我們在上面示例中新增以下函式:
void fn (b arg) {}
此函式的引數型別為b,但也可以傳入a型別引數(b類中定義了對a的型別轉換)
fn (foo);
這可能是預期的,也可能不是預期的。但是,無論如何,我們可以通過使用explicit
關鍵字修飾建構函式來防止它:
// explicit:
#include using namespace std;
class a {};
class b
b& operator= (const a& x)
operator a()
};void fn (b x) {}
int main ()
另外,標記為的建構函式explicit
無法使用類似賦值的語法來呼叫;在上面的示例中,bar
不能使用以下方法構造:
b bar = foo;
(2)型別轉換
c++是一種強型別的語言,很多地方都需要強型別轉換;通用的型別轉換存在兩種語法:函式式與類c式:
double x = 10.3;
int y;
y = int (x); // functional notation
y = (int) x; // c-like cast notation
這些通用的型別轉換足以滿足大多數基本型別的需求。但這些運算子不加區別地應用於類和指向類的指標上,會導致執行時錯誤。例如以下**,可以正常編譯,執行時會奔潰:
// class type-casting
#include using namespace std;
class dummy ;
class addition
int result()
};int main ()
為了控制這些型別之間的轉換,我們有四個具體的型別轉換符:dynamic_cast
,reinterpret_cast
,static_cast
和const_cast
(3)
dynamic_cast
dynamic_cast只能與類的指標、引用(或void*)一起使用。它目的是確保型別轉換的結果指向乙個有效完整的物件。
這自然包括指標向上轉換(從指標從派生類到基類的轉換),其方式與隱式轉換所允許的方式相同。
除此之外還支援向下轉換:
// dynamic_cast
#include #include using namespace std;
class base };
class derived: public base ;
int main () catch (exception& e)
return 0;
}
dynamic_cast
還可以執行指標所允許的其他隱式強制轉換:在指標型別之間(甚至在不相關的類之間)轉換空指標,並將任何型別的任何指標轉換為void*
指標。
(4)static
_cast
static_cast
可以在關聯的兩個類的指標間執行轉換,不僅支援向上轉換,還可以向下轉換。執行是不執行任何檢查。因此程式設計師要確保轉換是安全的。
class base {};
class derived: public base {};
base * a = new base;
derived * b = static_cast(a);
這將是有效的**,儘管b
會指向該類的不完整物件,並且如果取消引用可能會導致執行時錯誤。
static_cast
還可以執行所有隱式允許的轉換(不僅是那些指向類的指標)。它可以
此外,static_cast
還可以用於以下操作:
(5)reinterpret
_cast
reinterpret_cast
將任何指標型別轉換為任何其他指標型別,即使是不相關的類。運算結果是從乙個指標到另乙個指標的值的簡單二進位制副本。允許所有指標轉換:既不檢查指向的內容,也不檢查指標型別本身。
它還可以將指標轉換為整數型別或從整數型別轉換。該整數值表示指標的格式是特定於平台的。唯一的保證是,將指標強制轉換為足夠大以完全包含整數的整數型別(例如intptr_t
),可以保證將其強制轉換回有效指標。
可以執行reinterpret_cast
但不能執行的轉換static_cast
是基於重新解釋型別的二進位制表示形式的低階操作,這在大多數情況下會導致**特定於系統,因此不可移植。例如:
class a ;
class b ;
a * a = new a;
b * b = reinterpret_cast(a);
(6)const
_cast
這種型別轉換可以去除修飾變數的const關鍵字,例如:
// const_cast
#include using namespace std;
void print (char * str)
int main ()
(7)標準庫與boost庫中提供的型別轉換
字元和數字轉換的函式:
string型別與數值型別之間的轉換:
boost中的型別轉換操作符:
文章參考:c++ primer plus(第六版)
C 中的型別轉換
和goto語句一樣型別轉換的名聲似乎也是不那麼好。不過型別轉換在某些緊要關頭就顯得尤為重要,看看現有的c c 就知道,以至於你不理解轉換的作用,將是無法閱讀的。就像鈾,它能變成原子彈,但它也能用來發電,是災難還是福祉那就要看人類了。顯然型別轉換默默承受著這不公的一切。不管怎麼說c風格的型別轉換還是不...
C 中的型別轉換
1.隱式轉換 1 賦值轉換 將右值轉換為左型別,然後再賦值。2 整型提公升 c 將bool char,unsigned char,singned char,short轉換為int,int計算最快 表示式中的優先順序轉換 long double double float unsigned long 對...
C 中的型別轉換
我們知道 變數的型別定義了物件能包含的資料和參與的運算。其中一種運算被大多數型別支援,就是將變數從某一種給定的型別轉化為另外的型別。在了解型別轉換種類之前,首先牢記 型別轉換只是暫時的,原來的變數型別並不改變。在c語言中,分為兩種型別轉換 1,隱式型別轉換 2,顯示型別轉換 例如 double d ...