C++強制類型轉換
阿新 • • 發佈:2018-12-06
編譯 16進制 安全 pri ase 整形 強制 基類 圖片
本文介紹C++的四種強制類型轉換,轉載請註明出處。
一、const_cast:
去除指針或引用的const屬性。
1、轉化常量指針為非常量的指針,並且仍然指向原來的對象;
2、轉化常量引用為非常量的引用,並且仍然指向原來的對象;
3、const_cast一般用於修改指針。如const int *ptr形式。
用法:
#include <iostream> using namespace std; void main(){ cout << "const_cast測試" << endl; int ary[4] = { 1, 2, 3, 4}; const int *c_ary = ary; //c_ary[0] = 5;//錯誤,常量不能改變 int *ary2 = const_cast<int*>(c_ary);//const_cast將常量指針轉化為非常量指針 ary2[0] = 5;//正確 int a = 2; const int &c_a = a; //c_a = 5;//錯誤,常量不能改變 int &a2 = const_cast<int&>(c_a);//const_cast將常量引用轉化為非常量引用 a2 = 5;//正確 constint c_val = 3; int &ref_val = const_cast<int&>(c_val);//得到去const的引用 int *ptr_val = const_cast<int*>(&c_val);//得到去const的指針 system("pause"); }
二、static_cast
轉換數據類型,類的上下行轉換。
1、轉換數據類型,由於沒有運行時類型檢查來保證轉換的安全性,不安全;
2、類的上下行轉換,由於沒有運行時類型檢查,下行轉換不安全;
3、static_cast不能轉換掉原有類型的const、volatile、或者 __unaligned屬性;
c++ 的任何的隱式轉換都是使用 static_cast 來實現。
#include <iostream> using namespace std; void main(){ cout << "static_cast測試" << endl; float f_pi = 3.1415; int i_pi = static_cast<int>(f_pi); //類的上下行轉換 class Base{ }; class Derived :public Base{ }; //上行轉換 Derived->Base,安全 Derived derived; Base *base_ptr = static_cast<Base*>(&derived); //下行轉換 Base->Derived,由於沒有動態類型檢查,編譯能通過但不安全 Base base; Derived *derived_ptr = static_cast<Derived*>(&base); system("pause"); }
三、dynamic_cast
安全的上下行轉換。
上行轉換(子類到基類的指針轉換),dynamic_cast成功轉換,運行正常且輸出預期結果。而下行轉換(基類到子類的轉換),dynamic_cast在轉換時也沒有報錯,但是輸出給base2deri是空指針,說明dynami_cast在程序運行時對類型轉換對“運行期類型信息”(Runtime type information,RTTI)進行了檢查,是安全的(轉換後為空指針,不會指向未知內存,保證了使用安全)。而用static_cast由於沒有動態類型檢查,編譯能通過但不安全。
#include <iostream> using namespace std; class Base{ public: Base() {} ~Base() {} void print() { std::cout << "This is Base" << endl; } virtual void virtual_foo() {} }; class Derived : public Base{ public: Derived() {} ~Derived() {} void print() { std::cout << "This is Derived" << endl; } virtual void virtual_foo() {} }; void main(){ cout << "dynamic_cast測試" << endl; //上行轉換 Derived->Base Derived *derived = new Derived(); derived->print();//輸出This is Derived Base* deri2base = dynamic_cast<Base*>(derived); if (deri2base != nullptr){ derived->print();//輸出This is Base } //下行轉換 Base->Derived Base *base = new Base(); base->print();//輸出This is Base Derived* base2deri = dynamic_cast<Derived*>(base); if (base2deri != nullptr){//base2deri為空,不進行打印 base2deri->print(); } Base *base2 = new Derived(); base2->print();//輸出This is Base //Derived* deri2 = new Base();//錯誤。不能直接將Base*轉換為Derived*,即不能直接下行轉換。 delete derived; derived = nullptr; delete base; base = nullptr; system("pause"); }
輸出:
四、reinterpret_cast
進行無關類型的轉換
用在任意的指針間的轉換,任意引用間的轉換,指針和足夠大的整型之間的轉換,整型到指針的轉換。
#include <iostream> using namespace std; void main(){ int *p = new int(5); cout << "p的地址: " << hex << p << endl;//std::hex用於以16進制輸出十進制數 int p_addr = reinterpret_cast<int>(p); cout << "p_addr的值: " << hex << p_addr << endl; delete p; p = nullptr; system("pause"); }
輸出:
可見已經將指針p轉換為了int型,指針p的地址的值和整形p_addr的數值相同,都為0x44b4b8。
C++強制類型轉換