C++的強(qiáng)制類型轉(zhuǎn)換,除了繼承自C語言的寫法((目標(biāo)類型)表達(dá)式
)之外,還新增了4個(gè)關(guān)鍵字,分別是:static_cast
、dynamic_cast
、const_cast
和reinterpret_cast
。用法:xxx_cast<目標(biāo)類型>(表達(dá)式)
。由于后兩者的使用頻率較少,尤其是reinterpret_cast
的風(fēng)險(xiǎn)性很高,所以就不展開講了。這里主要將static_cast
和dynamic_cast
。
創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),都蘭網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:都蘭等地區(qū)。都蘭做網(wǎng)站價(jià)格咨詢:028-86922220
所謂static_cast,顧名思義,就是靜態(tài)的轉(zhuǎn)換,是在編譯期間就能確定的轉(zhuǎn)換。
#include
using namespace std;
int main()
{
float f = 5.67;
auto i = static_cast(f);
cout << i << endl; // 輸出結(jié)果:5
return 0;
}
#include
using namespace std;
class Src
{
public:
void foo()
{
cout << "This is Src" << endl;
}
};
class Dest
{
public:
/** 類型轉(zhuǎn)換構(gòu)造函數(shù) */
Dest(const Src &from)
{
cout << "Converting from Src to Dest" << endl;
}
void foo()
{
cout << "This is Dest" << endl;
}
};
int main()
{
Src src;
auto dst = static_cast(src); // 輸出結(jié)果:Converting from Src to Dest
dst.foo(); // 輸出結(jié)果:This is Dest
}
dynamic_cast
。#include
using namespace std;
class Base
{
public:
void foo()
{
cout << "This is Base" << endl;
}
};
class Derived : public Base
{
public:
void foo()
{
cout << "This is Derived" << endl;
}
};
void test_upcast()
{
Derived derived;
Derived *pDerived = &derived;
auto pBase = static_cast (pDerived);
pBase->foo(); // 輸出結(jié)果:This is Base
}
void test_downcast()
{
Base base;
Base *pBase = &base;
auto pDerived = static_cast(pBase); // 不安全:pa并沒有真正指向B類對(duì)象
pDerived->foo(); // 輸出結(jié)果:This is Derived。這里雖然輸出了結(jié)果,但是不安全
}
int main()
{
test_upcast();
test_downcast();
return 0;
}
所謂dynamic_cast,顧名思義就是動(dòng)態(tài)的轉(zhuǎn)換,是一種能夠在運(yùn)行時(shí)檢查安全性的轉(zhuǎn)換。
使用條件:
用于繼承體系中的上行或下行轉(zhuǎn)換。上行轉(zhuǎn)換跟static_cast
是一樣的;下行轉(zhuǎn)換會(huì)在運(yùn)行時(shí)動(dòng)態(tài)判斷。如果目標(biāo)類型并沒有指向?qū)ο蟮膶?shí)際類型,那么:
nullptr
std::bad_cast
異常#include
using namespace std;
class Base
{
public:
virtual void foo()
{
cout << "This is Base" << endl;
}
};
class Derived : public Base
{
public:
void foo() override
{
cout << "This is Derived" << endl;
}
};
/** Derived * -> Base * */
void test_upcast_ptr()
{
Derived derived;
Derived *pDerived = &derived;
auto base = dynamic_cast (pDerived); // 嘗試將派生類指針轉(zhuǎn)換為基類指針
if (base)
{
cout << "Derived * -> Base * was successful" << endl;
}
else
{
cout << "Derived * -> Base * failed" << endl;
}
}
/** Base * -> Derived * */
void test_downcast_ptr1()
{
Derived derived;
Base *pBase = &derived; // 基類指針指向派生類對(duì)象
auto pDerived = dynamic_cast(pBase); // 嘗試將指向派生類對(duì)象的基類指針轉(zhuǎn)換為派生類指針
if (pDerived)
{
cout << "Base * -> Derived * was successful" << endl;
}
else
{
cout << "Base * -> Derived * failed" << endl;
}
}
/** Base * -> Derived * */
void test_downcast_ptr2()
{
Base base;
Base *pBase = &base;
auto derived = dynamic_cast(pBase); // 嘗試將指向基類對(duì)象的基類指針轉(zhuǎn)換為派生類指針
if (derived)
{
cout << "Base * -> Derived * was successful" << endl;
}
else
{
cout << "Base * -> Derived * failed" << endl;
}
}
/** Derived & -> Base & */
void test_upcast_ref()
{
Derived derived;
Derived &refDerived = derived;
try
{
auto &base = dynamic_cast (refDerived); // 嘗試將派生類引用轉(zhuǎn)換為基類引用
cout << "Derived & -> Base & was successful" << endl;
}
catch (bad_cast &)
{
cout << "Derived & -> Base & failed" << endl;
}
}
/** Base & -> Derived & */
void test_downcast_ref1()
{
Derived derived;
Base &refBase = derived; // 基類引用指向派生類對(duì)象
try
{
auto &refDerived = dynamic_cast(refBase); // 嘗試將指向派生類對(duì)象的基類引用轉(zhuǎn)換為派生類引用
cout << "Base & -> Derived & was successful" << endl;
}
catch (bad_cast &)
{
cout << "Base & -> Derived & failed" << endl;
}
}
/** Base & -> Derived & */
void test_downcast_ref2()
{
Base base;
Base &refBase = base;
try
{
auto &refDerived = dynamic_cast(refBase); // 嘗試將指向基類對(duì)象的基類引用轉(zhuǎn)換為派生類引用
cout << "Base & -> Derived & was successful" << endl;
}
catch (bad_cast &)
{
cout << "Base & -> Derived & failed" << endl;
}
}
int main()
{
test_upcast_ptr(); // Derived * -> Base * was successful
test_downcast_ptr1(); // Base * -> Derived * was successful
test_downcast_ptr2(); // Base * -> Derived * failed
test_upcast_ref(); // Derived & -> Base & was successful
test_downcast_ref1(); // Base & -> Derived & was successful
test_downcast_ref2(); // Base & -> Derived & failed
}