四種轉換運算子
- const_cast:移除/增加
const / volatile 資格。
- dynamic_cast:執行期型別檢查,支援向下/橫向轉型(需多態基類別)。
- reinterpret_cast:位元層級重新解釋,不改變位址(指標轉整數、不相關指標互轉)。
- static_cast:編譯期靜態轉型,支援基本型別轉換、上行轉型、有轉換建構函式的類別轉換。
程式碼示範
/* cppprimer.cpp
* Created on: 2014.2.10
* Author: Spike
*/
#include <iostream>
struct S { S() : value(0) {} int value; };
void CastConst() {
const S s;
cout << "s.value = " << s.value << endl;
S* ps = const_cast<S*>(&s);
ps->value = 1;
cout << "s.value = " << s.value << endl;
S& rs = const_cast<S&>(s);
rs.value = 2;
cout << "s.value = " << s.value << endl;
}
struct B { virtual void f() { cout << "Base::f" << endl; } virtual ~B() {} };
struct B2 { virtual void g() { cout << "Base2::g" << endl; } virtual ~B2() {} };
struct D : public B, public B2 {
virtual void f() { cout << "Derived::f" << endl; }
virtual void g() { cout << "Derived::g" << endl; }
virtual ~D() {}
};
void CastDynamic() {
B* pB_D = new D;
pB_D->f();
D* pD_D = dynamic_cast<D*>(pB_D); // 向下轉型
pD_D->g();
B2* pB2_D = dynamic_cast<B2*>(pB_D); // 橫向轉型
pB2_D->g();
D* pD_Ds = static_cast<D*>(pB_D); // static_cast 也可向下,但無執行期檢查
pD_Ds->g();
// B2* pB2_Ds = static_cast<B2*>(pB_D); // 錯誤:static_cast 不能橫向轉型
delete pB_D;
}
struct rA { int m_a; };
struct rB { int m_b; };
struct rC : public rA, public rB {};
void CastReinterpret() {
int* i = new int(10);
cout << "*i = " << *i << ", i = " << i << endl;
double* d = reinterpret_cast<double*>(i);
cout << "*d = " << *d << ", d = " << d << endl;
rC c;
cout << "&c = " << &c << endl
<< "reinterpret_cast<rB*> = " << reinterpret_cast<rB*>(&c) << endl
<< "static_cast<rB*> = " << static_cast<rB*>(&c) << endl
<< "reinterpret_cast<rA*> = " << reinterpret_cast<rA*>(&c) << endl
<< "static_cast<rA*> = " << static_cast<rA*>(&c) << endl;
delete i;
}
int main() {
cout << "=== const_cast ===\n"; CastConst();
cout << "=== dynamic_cast ===\n"; CastDynamic();
cout << "=== reinterpret_cast ===\n"; CastReinterpret();
}
輸出節錄
=== const_cast ===
s.value = 0
s.value = 1
s.value = 2
=== dynamic_cast ===
Derived::f
Derived::g
Derived::g
Derived::g
=== reinterpret_cast ===
*i = 10, i = 0x...
*d = 2.55917e-307, d = 0x...
&c = 0x...
reinterpret_cast<rB*> = 0x...
static_cast<rB*> = 0x... (位址不同,static_cast 會調整位址)
reinterpret_cast<rA*> = 0x...
static_cast<rA*> = 0x... (rA 為第一基類別,位址相同)
選擇指南
- 移除
const → const_cast。
- 多態基類別指標向下/橫向轉型 →
dynamic_cast(需 RTTI)。
- 基本型別、enum、指標轉整數、不相關指標互轉 →
reinterpret_cast。
- 其他靜態可知的安全轉換 →
static_cast。