static_cast
- 用于類層次結(jié)構(gòu)中,基類和子類之間指針和引用的轉(zhuǎn)換。
- 進(jìn)行上行轉(zhuǎn)換,也就是把子類的指針或引用轉(zhuǎn)換成父類表示,這種轉(zhuǎn)換是安全的;
- 當(dāng)進(jìn)行下行轉(zhuǎn)換,也就是把父類的指針或引用轉(zhuǎn)換成子類表示,這種轉(zhuǎn)換是不安全的,也需要程序員來保證;
- 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換,如把int轉(zhuǎn)換成char,把int轉(zhuǎn)換成enum等等,這種轉(zhuǎn)換的安全性需要程序員來保證
- 把void指針轉(zhuǎn)換成目標(biāo)類型的指針,是及其不安全的;
#include "iostream";
using namespace std;
class Parent {
public:
Parent() {
cout << "構(gòu)造Parent" << endl;
}
Parent(const Parent&) {
cout << "Parent拷貝構(gòu)造" << endl;
}
virtual void print() {
cout << "Parent print" << endl;
}
void eat() {
cout << "Parent eat" << endl;
}
};
class Child :public Parent{
public:
Child() {
cout << "構(gòu)造Child" << endl;
}
Child(const Child &c) {
cout << "Child拷貝構(gòu)造" << endl;
}
virtual void print() {
cout << "Child print" << endl;
}
void eat() {
cout << "Child eat" << endl;
}
};
int main()
{
Child c;
Parent& p = static_cast<Parent&>(c);
p.print();
cout << "-------" << endl;
//這里相當(dāng)于Parent pp=c;會調(diào)用Parent的拷貝構(gòu)造函數(shù)
Parent pp = static_cast<Parent>(c);
pp.print();
cout << "-------" << endl;
Parent* ppp = static_cast<Parent*>(&c);
ppp->print();
int n = 10;
void * nn = &n;
//void* 進(jìn)行轉(zhuǎn)換目標(biāo)類型指針,可以但不安全
int *nnn = static_cast<int *>(nn);
cout << *nnn << endl;
//這里編譯提示報錯
//char *c = static_cast<char *>(nnn);
return 0;
}
結(jié)果:
結(jié)果
dynamic_cast
- dynamic_cast主要用于類層次間的上行轉(zhuǎn)換和下行轉(zhuǎn)換,還可以用于類之間的交叉轉(zhuǎn)換。在類層次間進(jìn)行上行轉(zhuǎn)換時,dynamic_cast和static_cast的效果是一樣的;在進(jìn)行下行轉(zhuǎn)換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。
//使用前面定義的類
int main()
{
Child c;
Parent* p = dynamic_cast<Parent*>(&c);
p->print();
cout << "-----" << endl;
Child *cc = dynamic_cast<Child*>(p);
cc->print();
cout << "-----" << endl;
Parent& pp = dynamic_cast<Parent&>(c);
pp.print();
cout << "-----" << endl;
Child& ccc = dynamic_cast<Child&>(pp);
ccc.print();
cout << "-----" << endl;
//編譯失敗。轉(zhuǎn)換后的類型必須為指針或引用
//Parent ppp = dynamic_cast<Parent>(c);
return 0;
}
結(jié)果:
結(jié)果
const_cast
- const_cast用來將類型的const、volatile和__unaligned屬性移除。常量指針被轉(zhuǎn)換成非常量指針,并且仍然指向原來的對象;常量引用被轉(zhuǎn)換成非常量引用,并且仍然引用原來的對象。
- 不能直接對非指針和非引用的變量使用const_cast操作符去直接移除它的const、volatile和__unaligned屬性。
int main()
{
char buf[20] = "abcd";
const char *p = buf;
//編譯報錯,const修飾的內(nèi)容無法修改
//p[0] = '1';
char *pp = const_cast<char *>(p);
pp[0] = '1';
cout << pp << endl;
const char *str = "abcd";
char *strp = const_cast<char *>(str);
//這句運行出錯,常量指針被轉(zhuǎn)換成非常量指針,并且仍然指向原來的對象。而原來的"abcd"不可修改
//*strp = '1';
//不能直接對非指針和非引用的變量使用const_cast操作符去直接移除它的const、volatile和__unaligned屬性。
//int j = const_cast<int>(i);
return 0;
}
reinterpret_cast
允許將任何指針類型轉(zhuǎn)換為其它的指針類型;聽起來很強(qiáng)大,但是也很不靠譜。它主要用于將一種數(shù)據(jù)類型從一種類型轉(zhuǎn)換為另一種類型。它可以將一個指針轉(zhuǎn)換成一個整數(shù),也可以將一個整數(shù)轉(zhuǎn)換成一個指針,在實際開發(fā)中,先把一個指針轉(zhuǎn)換成一個整數(shù),在把該整數(shù)轉(zhuǎn)換成原類型的指針,還可以得到原來的指針值;特別是開辟了系統(tǒng)全局的內(nèi)存空間,需要在多個應(yīng)用程序之間使用時,需要彼此共享,傳遞這個內(nèi)存空間的指針時,就可以將指針轉(zhuǎn)換成整數(shù)值,得到以后,再將整數(shù)值轉(zhuǎn)換成指針,進(jìn)行對應(yīng)的操作。
int main()
{
char buf[20] = "abcd";
int *p = reinterpret_cast<int *>(buf);
char *pp = reinterpret_cast<char *>(p);
cout << buf << endl << p << endl << pp << endl;;
return 0;
}