1. 程式人生 > >C++強制類型轉換

C++強制類型轉換

編譯 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;//正確 const
int 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++強制類型轉換