C/C++編程中男旗,通常會需要對類型進行轉(zhuǎn)換舶斧,以符合編程需要。在C語言中察皇,有兩種轉(zhuǎn)換方式:隱式轉(zhuǎn)換和強制類型轉(zhuǎn)換茴厉。那么C++中有哪些方式呢。
- static_cast 靜態(tài)類型轉(zhuǎn)換
- reinterpret_cast 重解析類型轉(zhuǎn)換
- dynamic_cast 動態(tài)類型轉(zhuǎn)換
- const_cast 去只讀屬性轉(zhuǎn)換
下面什荣,我們來一一介紹他們的使用場景和使用方法矾缓。
靜態(tài)類型轉(zhuǎn)換
static_cast
靜態(tài)類型轉(zhuǎn)換,一般用在比如int
和char
的轉(zhuǎn)換上稻爬,也就是說嗜闻,只要C語言中能夠隱式轉(zhuǎn)換的所有類型都可以使用static_cast
進行轉(zhuǎn)換。如果類型不能兼容桅锄,編譯階段會報錯琉雳。
- 能使用隱式轉(zhuǎn)換的地方样眠,均可以使用
static_cast
轉(zhuǎn)換 - 如果類型不兼容,使用
static_cast
編譯檢查翠肘,會報錯
int main(int argc, const char * argv[]) {
double dpi = 3.1415926;
//C類型轉(zhuǎn)換
int num1 = (int)dpi;
//靜態(tài)類型轉(zhuǎn)換
int num2 = static_cast<int>(dpi);
//C語言中檐束,隱式類型轉(zhuǎn)換的地方均可使用 static_cast<>()進行轉(zhuǎn)換
int num3 = dpi;
//靜態(tài)類型轉(zhuǎn)換,編譯器會做類型檢查,類型不兼容,會報錯
char *p1 = "hello world";
int *p2 = static_cast<int *>(p1);
return 0;
}
重解析類型轉(zhuǎn)換
我們可以使用statci_cast
來替代隱式轉(zhuǎn)換束倍。但是如果碰到上述類型不兼容的情況被丧,C語言可以使用(int)a
強制類型轉(zhuǎn)換來處理,那么C++該如何處理呢绪妹?
C++中可以通過重解析類型轉(zhuǎn)換reinterpret_cast
來實現(xiàn)C語言的強制類型轉(zhuǎn)換的效果晚碾。C++會將類型進行重新解析,轉(zhuǎn)換成你需要的類型喂急,不考慮轉(zhuǎn)換后的后果格嘁。
int main(int argc, const char * argv[]) {
//重解析類型轉(zhuǎn)換,前置進行類型轉(zhuǎn)換
char *p1 = "hello world";
int *p2 = reinterpret_cast<int *>(p1);
cout<<p1<<endl;
cout<<p2<<endl;
return 0;
}
<a name="fenced-code-block">小結(jié)</a>
通過靜態(tài)類型轉(zhuǎn)換和重解析類型轉(zhuǎn)換完全可以替代C語言中的隱式轉(zhuǎn)換和強制類型轉(zhuǎn)換廊移。
動態(tài)類型轉(zhuǎn)換
dynamic_cast
動態(tài)類型轉(zhuǎn)換一般是用在父類和子類的轉(zhuǎn)換上糕簿。一個典型的應用場景類似于Objecive-C語言中的isKindOfClass
方法,可以動態(tài)的來判斷當前對象的真實類型狡孔。
#include <iostream>
using namespace std;
class Animal {
public:
virtual void cry() = 0;
};
class Dog : public Animal {
public:
void cry()
{
cout<<"狗叫"<<endl;
}
void todo()
{
cout<<"看門"<<endl;
}
};
class Cat : public Animal{
public:
void cry()
{
cout<<"貓叫"<<endl;
}
void doSome()
{
cout<<"睡懶覺"<<endl;
}
};
void test(Animal *base)
{
base->cry();
//強制轉(zhuǎn)換成Dog類懂诗,如果轉(zhuǎn)換不成功說明當前傳入的實際類型是Cat類
Dog *dog = dynamic_cast<Dog *>(base);
if (dog != NULL) {
//說明,當前傳入對象的實際類型是Dog類
dog->todo();
}
//強制轉(zhuǎn)換成Cat類苗膝,如果轉(zhuǎn)換不成功說明當前傳入的實際類型是Dog類
Cat *cat = dynamic_cast<Cat *>(base);
if (cat != NULL) {
//說明殃恒,當前傳入的對象的實際類型是Cat類
cat->doSome();
}
}
int main()
{
Dog dog;
Cat cat;
Animal *animal = &dog;
test(animal);
return 0;
}
在上面的例子中,是將父類動態(tài)轉(zhuǎn)換成子類辱揭±胩疲可以通過dynamic_cast
來抓換,從而動態(tài)的確認當前傳入對象的實際類型问窃。
去只讀屬性轉(zhuǎn)換
C++中const
關鍵字聲明的對象亥鬓,一般是常量,不能對其直接進行修改域庇。如果想要對傳入的const對象進行修改嵌戈,需要將當前對象進行去只讀屬性,從而進行更改听皿。
#include <iostream>
using namespace std;
void changeWord(const char *buf)
{
//報錯熟呛,提示當前是常量,不能修改
buf[0] = '9';
}
int main()
{
char buf[] = "123456789";
changeWord(buf);
cout<<buf<<endl;
return 0;
}
編譯上述代碼后尉姨,會報錯庵朝,提示buf是只讀的。如果我們想要修改怎么辦?可以使用const_cast
轉(zhuǎn)換偿短,從而可以修改欣孤。修改后的changeWord
方法如下。
void changeWord(const char *buf)
{
//使用const_cast轉(zhuǎn)換去常量化昔逗,再進行修改
char *tmp = const_cast<char *>(buf);
tmp[0] = '9';
}
通過const_cast
可以將只讀屬性去掉降传,修改對應的數(shù)據(jù)。但是需要注意的是勾怒,當前的指針直線的內(nèi)存空間是可讀的婆排。比如說:如果傳給changeWord是一個常量,只能讀笔链,不能改段只。
void changeWord(const char *buf)
{
//此時buf指向的數(shù)據(jù)是一個常量,不僅僅是只讀屬性
//const char *buf = "123456789" 常量不可更改
//使用const_cast轉(zhuǎn)換去只讀屬性鉴扫,仍然不能進行修改
char *tmp = const_cast<char *>(buf);
tmp[0] = '9';
}
int main()
{
//是字符串指針
char *buf = "123456789";
changeWord(buf);
cout<<buf<<endl;
return 0;
}