C++四種類型轉換


C風格的強制類型轉換(Type Cast)很簡單,不管什么類型的轉換統統是:

TYPE b = (TYPE)a   

C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用。

     static_cast                 靜態類型轉換。如int轉換成char

                  reinterpreter_cast  重新解釋類型

            dynamic_cast            命名上理解是動態類型轉換。如子類和父類之間的多態類型轉換。

       const_cast,             字面上理解就是去const屬性。

4種類型轉換的格式:

         TYPE B = static_cast<TYPE> (a) 

 

一般性介紹

1)static_cast<>()   靜態類型轉換,編譯的時c++編譯器會做類型檢查

基本類型能轉換 但是不能轉換指針類型

         2)若不同類型之間,進行強制類型轉換,用reinterpret_cast<>() 進行重新解釋

         3)一般性結論:

C語言中  能隱式類型轉換的,在c++中可用 static_cast<>()進行類型轉換。因C++編譯器在編譯檢查一般都能通過;

C語言中不能隱式類型轉換的,在c++中可以用 reinterpret_cast<>() 進行強行類型 解釋。總結:static_cast<>()和reinterpret_cast<>() 基本上把C語言中的 強制類型轉換給覆蓋

reinterpret_cast<>()很難保證移植性。

         4)dynamic_cast<>(),動態類型轉換,安全的基類和子類之間轉換;運行時類型檢查

         5)const_cast<>(),去除變量的只讀屬性

典型案例

static_cast和reinterpreter_cast
#include <iostream>
using  namespace std;

int main()
{
    double dpi = 3.1415926;

    int num1 = (int)dpi;  // c類型轉換
    int num2 = static_cast<int> (dpi); // c++靜態類型轉換, 編譯時編譯器會進行類型檢查
    int num3 = dpi;      // c語言中,隱士類型轉換的地方,去可以使用,有警告,但是加上Static_cast就沒了

    // char* ===> int*
    char *p1 = "hello world";
    int  *p2 = NULL;

    // p2 = static_cast<int*>(p1);  // 編譯器會進行類型檢查,有錯就提示出來

    p2 = reinterpret_cast<int*> (p1);

    cout << "p1 = " << p1 <<endl;  //%s 一個字符串,如果是*p1就是h
    cout << "p2 = " << p2 << endl; //%d 字符串的首地址

    // 總結:通過reinterpreter_cast<>(),static_cast<>(),把c語言中的強制類型都覆蓋了
    return 0;

}

//結果
//p1 = hello world
//p2 = 0x47f048

 

dynamic_cast用法和reinterpret_cast用法

#include <iostream>
using  namespace std;

/*
    C分格的強制類型轉換(Type cast),很簡單,不管什么類型,都是
    Type b = (Type)a;

    C++風格提供了4種類型轉換操作符,來對應不同的場合的應用
        static_cast    靜態類型轉換,如int轉換成char
        reinterpreter_cast  重新解釋類型
        dynamic_cast       命名上理解動態類型轉換,如子類和父類之間的多態類型轉換
        const_cast     字面理解就是const屬性

        4中類型轉換格式:
        Type b = static_cast<Type> (a);
*/
class Animal
{
public:
    virtual void cry() = 0;
};

class Dog : public Animal
{
public:
    virtual void cry()  // 虛函數重寫
    {
        cout <<"\t汪汪" << endl;
    }
    void doHome()
    {
        cout << "\t看家" << endl;
    }
};

class Cat : public Animal
{
public:
    virtual void cry()
    {
        cout << "\t喵喵" <<endl;
    }
    void doThing()
    {
        cout << "\t抓老鼠" << endl;
    }
};

// 對象唱戲,發生多態, 只能用指針或者引用
void playObj(Animal &base)
{
    base.cry(); // 1有繼承, 2 虛函數重寫,3父類指針(引用) 指向子類對象 ===> 發生多態
    cout << endl;

    // 需求:識別子類對象
    // dynamic_cast 運行時類型識別

    Dog *pDog = dynamic_cast<Dog *> (&base);
    if (pDog != NULL)
    {
        pDog->doHome();  // 做自己特有的工作
    }

    cout << endl;

    Cat *c1 = dynamic_cast<Cat *> (&base);  // 父類對象 ==> 子類對象
                                           // 向下轉型
                                          // 把老子轉成小子
    if (c1 != NULL)
    {
        c1->doThing();
    }

}
class Tree{};
int main()
{
    Dog d1;
    Cat c1;

    Animal *pBase = NULL;
    pBase = &d1;
    pBase = static_cast<Animal*>(&d1); // c++編譯時,進行類型檢查,將d1指針轉換成父類指針

    // 強制類型轉換
    pBase = reinterpret_cast<Animal*>(&d1);

    {
        Tree t1;
        // 將樹指針 轉換成動物類指針
//        pBase = static_cast<Animal*>      (&t1);  // c++編譯器,類型檢查 不通過
        pBase = reinterpret_cast<Animal*> (&t1); // 可以 重新解釋。。。。強制類型轉換的味道

    }
    playObj(d1);
    playObj(c1);
    return 0;
}

//結果
// 汪汪
//
// 看家
//
// 喵喵
//
//
// 抓老鼠

 

 const_cast用法

// const char*p,中得const表示 p指向的內存空間 不可以修改 就是*p(值)不能改
void printBuf(const char*p)
{
//     p[0] = 't';  報錯

    char *p1 = NULL;

    // 程序員要清楚地知道:變量轉換前,和轉換后的類型
    p1 = const_cast<char*>(p);   // 將p 由const char* == > char*
    cout << "p = " << p << endl;

    p1[1] = 't';  // 通過p1修改了 p指向的內存空間

    // 轉換后 可以間接修改p的值,不准換的話,也不能間接修改
    cout << "p = " << p << endl;

}

int main()
{
     char buf[] = "aaaaa";
    // 程序員 要確保 p所指向的內存空間,確實能修改,如果不能修改,會帶來災難性的后果
     printBuf(buf);

//    char *myBuf = "bbbbbbbb";  // 常量,不能修改
//    printBuf(myBuf);
    return 0;
}

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM