C++ 的型別轉換有以下四種轉換方式 分別是 static_cast, dynamic_cast,reinterpret_cast 以及const_cast .分述如下:
static_cast
可用於轉換基底類別指標為衍生類別指標,也可用於傳統的資料型態轉換。
舉例來說,在指定的動作時,如果右邊的數值型態比左邊的數值型態型態長度大時,
超出可儲存範圍的部份會被自動消去,例如將浮點數指定給整數變數,則小數的部份會被自動消去
Ex: int num1 = 0; double num2 = 1.11; num1 = static_cast<int>(num2);dynamic_cast
使用static_cast(甚至是傳統的C轉型方式)將基底類別指標轉換為衍生類別指標,
這種轉型方式稱為強制轉型,但是在執行時期使用強制轉型有危險性,
因為編譯器無法得知轉型是否正確.
Ex:
#include <iostream>
struct Base {
virtual ~Base() {}
virtual void name() {}
};
struct Derived: Base {
virtual ~Derived() {}
virtual void name() {}
};
struct Some {
virtual ~Some() {}
};
int main()
{
Some *s = new Some;
Base* b1 = new Base;
Base* b2 = new Derived;
Derived *d1 = dynamic_cast<Derived*>(b1);
Derived *d2 = dynamic_cast<Derived*>(b2);
Derived *d3 = dynamic_cast<Derived*>(s);
Base *d4 = dynamic_cast<Base*>(s);
std::cout << "'b1' points to 'Derived'? : " << (bool) d1 << '\n';
std::cout << "'b2' points to 'Derived'? : " << (bool) d2 << '\n';
std::cout << "'s' points to 'Derived'? : " << (bool) d3 << '\n';
std::cout << "'s' points to 'Base'? : " << (bool) d4 << '\n';
}
Output:
i = 4
type::i = 4
'b1' points to 'Derived'? : false
'b2' points to 'Derived'? : true
's' points to 'Derived'? : false
's' points to 'Base'? : false
reinterpret_cast用於將一種型態的指標轉換為另一種型態的指標,例如將char*轉換為int*
Ex:
#include <iostream>
using namespace std;
int main() {
int i;
char* str = "test";
i = reinterpret_cast(str);
cout << i << endl;
return 0;
}
const_cast用於一些特殊場合可以覆寫變數的const屬性,利用cast後的指標就可以更改變數的內部。
const_cast是一危險的轉型"唯一使用"的場合是當物件資料屬性為const時但有時卻必須傳遞給非const參數的成員函數或一般全域函數時才可用它來移除const屬性因為唯有如此才可
符合型態相同(形式引數(參數))但使用時必須確定此轉型後不會藉此來更改其資料否則可能會造成無法預測的結果!!!
Ex:
#include <iostream>
struct type {
type():i(3)
{}
void m1(int v) const
{
const_cast<type*>(this)->i = v;
}
int i;
};
int main()
{
type t;
t.m1(4);
std::cout << "type::i = " << t.i << '\n';
}
Output:
type::i = 4