C++11新特性之四種類型轉(zhuǎn)換cast說明
引言
C++11引入了四種類型轉(zhuǎn)換接口,它們分別是static_cast、const_cast、dynamic_cast、reinterpret_cast。
為什么要使用這四種轉(zhuǎn)換呢?
給出面向?qū)ο缶幊毯兔嫦驅(qū)ο笤O(shè)計的五個基本原則,SOLID原則。
- Single Responsibility Principle:單一職責(zé)原則
- Open Closed Principle:開閉原則
- Liskov Substitution Principle:里氏替換原則
- Law of Demeter:迪米特法則
- Interface Segregation Principle:接口隔離原則
- Dependence Inversion Principle:依賴倒置原則
這里不詳細敘述五個基本原則,我們使用的cast接口和里氏替換原則有關(guān)。
里氏替換原則: “派生類(子類)對象可以在程式中代替其基類(超類)對象。” 以上內(nèi)容并非利斯科夫的原文,而是譯自羅伯特·馬?。≧obert Martin)對原文的解讀[1]。
1、static_cast
1.1 基本類型轉(zhuǎn)換
1.2 類的上行轉(zhuǎn)換(安全)
用于子類指針或引用轉(zhuǎn)換為父類指針或引用。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class"; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class"; }
};
int main()
{
Derived* der = new Derived;
auto Derived = static_cast<Base*> (der);
//向上轉(zhuǎn)換一直是安全的
Derived->Show();
system("pause");
}
輸出結(jié)果為
This is Derived class
存在虛函數(shù)重載,則父類的函數(shù)被隱藏不能使用。
由于使用dynamic_cast和static_cast方法會存在開銷,則一般使用下列方法進行向上轉(zhuǎn)換。
class Base
{
public:
Base(){};
virtual void Show(){cout<<"This is Base class";}
};
class Derived:public Base
{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main()
{
Base *base ;
Derived *der = new Derived;
//向上轉(zhuǎn)換總是安全
base = der;
base->Show();
system("pause");
}
1.3 類的下行轉(zhuǎn)換(不安全)
將父類指針、引用轉(zhuǎn)換為子類指針、引用,但需要程序員自己檢查,因此這種轉(zhuǎn)換方式也不存在額外的開銷。
2、const_cast
2.1 改變常量屬性
- 常量指針轉(zhuǎn)化為非常量指針;
- 常量引用轉(zhuǎn)化為非常量引用;
- 常量對象轉(zhuǎn)化為非常量對象
3、dynamic_cast
該轉(zhuǎn)換是運行時轉(zhuǎn)換,其余都是編譯時轉(zhuǎn)換。主要用于安全的向下進行轉(zhuǎn)換。同時當指針是智能指針時,使用dynamic_cast向下轉(zhuǎn)換不能成功,需使用dynamic_point_cast來進行轉(zhuǎn)換。
3.1 類的上行轉(zhuǎn)換(安全)
此處和static_cast是一樣的,不再過多敘述。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base calss"; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class"; }
};
int main()
{
Derived* der = new Derived;
auto Derived = dynamic_cast<Base*> (der);
//向上轉(zhuǎn)換一直是安全的
Derived->Show();
system("pause");
}
3.2 類的下行轉(zhuǎn)換(安全)
因為有類型檢查所以是安全的,但類型檢查需要運行時類型信息,這個信息位于虛函數(shù)表中,所以必須要有虛函數(shù),否則會轉(zhuǎn)換失敗。
在dynamic_cast轉(zhuǎn)換中分為兩種情況。
1、當基類指針指向派生對象時能夠安全轉(zhuǎn)換。
2、基類指針指向基類時會做檢查,轉(zhuǎn)換失敗,返回結(jié)果0。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
//第一種情況
Base* base = new Derived;
Derived* der = dynamic_cast<Derived*>(base);
//基類指針指向派生類對象時能夠安全轉(zhuǎn)換
der->Show();
//第二種情況
Base *base1 = new Base;
if (Derived* der1 = dynamic_cast<Derived*> (base1))
{
der1->Show();
}
else
{
cout << "error!";
}
delete(base);
delete(base1);
system("pause");
}
This is Derived class
error!
引用則和指針不同,指針在C++11中存在空指針,而引用不存在空引用,會引發(fā)bad_cast異常。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
//基類引用子類
Derived b;
Base& base1 = b;
Derived& der1 = dynamic_cast<Derived&>(base1);
der1.Show();
//基類引用基類
Base a;
Base& base2 = a;
try
{
Derived& der2 = dynamic_cast<Derived&>(base2);
}
catch(bad_cast)
{
cout << "bad_cast error!!" << endl;
}
system("pause");
}
This is Derived class
bad_cast error!!
4、reinterpret_cast
4.1 非關(guān)聯(lián)類型的轉(zhuǎn)換
操作結(jié)果是一個指針到其他指針的二進制拷貝,沒有類型檢查。
總結(jié)
到此這篇關(guān)于C++11新特性之四種類型轉(zhuǎn)換cast說明的文章就介紹到這了,更多相關(guān)C++11類型轉(zhuǎn)換cast內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++數(shù)據(jù)結(jié)構(gòu)之鏈表詳解
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之鏈表的創(chuàng)建的相關(guān)資料,希望通過本文幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2021-08-08
Qt數(shù)據(jù)庫應(yīng)用之超級自定義委托
Qt中需要用到自定義委托的情形很多,比如提供下拉框選擇,進度條展示下載進度啥的,默認的單元格是沒有這些效果的,需要自己單獨用委托的形式來展示。本文將為大家介紹Qt中如何進行超級自定義委托,需要的可以參考一下2022-03-03
VC外部符號錯誤_main,_WinMain@16,__beginthreadex解決方法
這篇文章主要介紹了VC外部符號錯誤_main,_WinMain@16,__beginthreadex解決方法,實例分析了比較典型的錯誤及對應(yīng)的解決方法,需要的朋友可以參考下2015-05-05

