c++---類型轉換

  1. C語言中的類型轉換
  2. C++強制類型轉換
  3. 爲什麼需要強制類型轉換
  4. RTTI

一,C語言中的類型轉換
在C語言中分爲了兩種類型轉換,一種是隱式類型轉換,但是隱式類型轉換是相鄰類型之間纔可以進行隱式類型轉換,比如我們的char可以轉爲int,這兩種都是表示數值的。第二種是強制類型轉換,強制類型轉換需要在前面聲明我們需要轉換的。比如將int類型轉換爲int*

#include <iostream>
using namespace std;

int main() {   
	int a = 10;
	char b = 5;
	a = b;//隱式類型轉換
	cout << a << endl;

	//強制類型轉換
	int* p = (int*)a;
	cout << p << endl;
	system("pause");
	return EXIT_SUCCESS;
}

缺陷:轉換的可視性比較差,所有的轉換形式都是以一種相同形式書寫。難以追蹤錯誤的轉換。

二,C++強制類型轉換
在c++中爲了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符

  • static_cast
    static_cast用來非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可以使用static_cast來轉換。但是不能轉換兩個不相關的類型。
#include <iostream>
using namespace std;

int main() {   
	int a = 10;
	char b = 5;
	a = static_cast<int>(b);//隱式類型轉換
	cout << a << endl;

	//強制類型轉換
	int* p = static_cast<int*>(a);
	cout << p << endl;
	system("pause");
	return EXIT_SUCCESS;
}

所明顯的是我們的int類型轉換爲int*類型出錯了。

  • reinterpret_cast
    reinterpret_cast操作符通常爲操作數的位模式提供較低層次的重新解釋,用於將一種類型轉換爲另一種不同的類型。(也就是我們常說的重新解釋,強制類型轉換)
	int* p = reinterpret_cast<int*>(a);
	cout << p << endl;

將上面的代碼改成reinterpret_cast就能夠成功編譯運行。

  • const_cast
    const_cast最常用的用途就是刪除變量的const屬性,方便賦值。
#include <iostream>
using namespace std;

int main() {   
	const int a = 10;
	int& b = const_cast<int&>(a);
	b = 20;
	cout << a << endl;
	cout << b << endl;
	system("pause");
	return EXIT_SUCCESS;
}

這裏我們常用的就是類型的指針或者引用,將我們的a的值重新定義到b,並且消除const常量。當我們修改b的時候a的值也會被修改。執行程序
在這裏插入圖片描述
a的值並沒有修改。
注意:const常量在使用的時候值是存放在寄存器中,每次使用的時候從寄存器中拿出,並不會從內存中取值。當修改爲20的時候都是內存中的值已經被修改了。使用關鍵字volatile。可以保證每次都是從內存中取值。

	volatile const int a = 10;
	
	volatile int& b = const_cast<int&>(a);

修改這兩行代碼。
在這裏插入圖片描述

  • dynamic_cast
    dynamic_cast用於將一個父類對象的指針轉換爲子類對象的指針或者引用(動態轉換)
    向上類型轉換:子類對象指針/引用->父類對象指針/引用,此時不需要轉換,賦值兼容規則
    向下類型轉換:父類對象指針/引用轉換爲子類對象的指針或者引用(只有使用dynamic_cast是安全的)。
    注意:
    1. dynamic_cast只能用於含有虛函數的類
    2. dynamic_cast會先價差是否能夠轉型成功,不能返回0;
#include <iostream>
using namespace std;
class A{
public:
	virtual void f(){};

};
class B :public A{


};

void fun(A* pa) {   
	// dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回  
	B* pb1 = static_cast<B*>(pa);  
	B* pb2 = dynamic_cast<B*>(pa);    
	cout<<"pb1:" <<pb1<< endl;   
	cout<<"pb2:" <<pb2<< endl; 
}

int main() {
	A a;   
	B b;    
	fun(&a);     
	fun(&b);   
	system("pause");
	return 0; 
}


在這裏插入圖片描述

  • explicit
    explicit關鍵字阻止經過轉換構造函數進行的隱式轉換的發生
#include <iostream>
using namespace std;
class A{
public:
	explicit A(int a){
		cout << "A(int a)" << endl;
	}
	A(const A&a){
		cout << "A(const A& a)" << endl;
	}
private:
	int _a;

};


int main() {
	A a1(1);
	A a2 = 1;//此時此就不可行了。直接報錯
	system("pause");
	return 0; 
}

在這裏插入圖片描述
三,爲什麼需要四種類型轉換
其實原因很簡單。就是爲了解決在c語言中遺留下來的問題。

  • 隱式轉換有些情況可能會出現問題
int main() {
	int a = 10;
	size_t b = 0;
	while (a >= b){
		cout << a << endl;
		a--;
	}

	system("pause");
	return 0; 
}

這種情況就會將a隱式轉換成size_t類型造成死循環。

  • 顯示類型轉換將所有情況混合在一起,代碼不清晰,也就是可讀性非常差。

四,RTTI
RTTI就是運行時類型識別
C++通過以下方式支持RTTI

  • typeid運算符
  • dynamic_cast運算符
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章