日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++11新特性之四種類型轉換cast說明_C 語言

作者:面條有點辣 ? 更新時間: 2023-04-19 編程語言

引言

C++11引入了四種類型轉換接口,它們分別是static_cast、const_cast、dynamic_cast、reinterpret_cast。

為什么要使用這四種轉換呢?

給出面向對象編程和面向對象設計的五個基本原則,SOLID原則。

  • Single Responsibility Principle:單一職責原則
  • Open Closed Principle:開閉原則
  • Liskov Substitution Principle:里氏替換原則
  • Law of Demeter:迪米特法則
  • Interface Segregation Principle:接口隔離原則
  • Dependence Inversion Principle:依賴倒置原則

這里不詳細敘述五個基本原則,我們使用的cast接口和里氏替換原則有關。

里氏替換原則: “派生類(子類)對象可以在程式中代替其基類(超類)對象。” 以上內容并非利斯科夫的原文,而是譯自羅伯特·馬丁(Robert Martin)對原文的解讀[1]

1、static_cast

1.1 基本類型轉換

1.2 類的上行轉換(安全)

用于子類指針或引用轉換為父類指針或引用。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base class"; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class"; }
};
int main()
{
    Derived* der = new Derived;
    auto  Derived = static_cast<Base*> (der);
    //向上轉換一直是安全的
    Derived->Show();
    system("pause");
}

輸出結果為

This is Derived class

存在虛函數重載,則父類的函數被隱藏不能使用。

由于使用dynamic_caststatic_cast方法會存在開銷,則一般使用下列方法進行向上轉換。

class Base
{
public:
    Base(){};
    virtual void Show(){cout<<"This is Base class";}
};
class Derived:public Base
{
public:
    Derived(){};
    void Show(){cout<<"This is Derived class";}
};
int main()
{
    Base *base ;
    Derived *der = new Derived;
    //向上轉換總是安全
    base = der; 
    base->Show();
    system("pause");
}

1.3 類的下行轉換(不安全)

將父類指針、引用轉換為子類指針、引用,但需要程序員自己檢查,因此這種轉換方式也不存在額外的開銷。

2、const_cast

2.1 改變常量屬性

  • 常量指針轉化為非常量指針;
  • 常量引用轉化為非常量引用;
  • 常量對象轉化為非常量對象

3、dynamic_cast

該轉換是運行時轉換,其余都是編譯時轉換。主要用于安全的向下進行轉換。同時當指針是智能指針時,使用dynamic_cast向下轉換不能成功,需使用dynamic_point_cast來進行轉換。

3.1 類的上行轉換(安全)

此處和static_cast是一樣的,不再過多敘述。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base calss"; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class"; }
};
int main()
{
    Derived* der = new Derived;
    auto  Derived = dynamic_cast<Base*> (der);
    //向上轉換一直是安全的
    Derived->Show();
    system("pause");
}

3.2 類的下行轉換(安全)

因為有類型檢查所以是安全的,但類型檢查需要運行時類型信息,這個信息位于虛函數表中,所以必須要有虛函數,否則會轉換失敗。
在dynamic_cast轉換中分為兩種情況。

1、當基類指針指向派生對象時能夠安全轉換。

2、基類指針指向基類時會做檢查,轉換失敗,返回結果0。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
    //第一種情況
    Base* base = new Derived;
    Derived* der = dynamic_cast<Derived*>(base);
    //基類指針指向派生類對象時能夠安全轉換
    der->Show();
    //第二種情況
    Base *base1 = new Base;

    if (Derived* der1 = dynamic_cast<Derived*> (base1))
    {
        der1->Show();
    }
    else
    {
        cout << "error!";
    }
    delete(base);
    delete(base1);
    system("pause");
}

This is Derived class
error!

引用則和指針不同,指針在C++11中存在空指針,而引用不存在空引用,會引發bad_cast異常。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
    //基類引用子類
    Derived b;
    Base& base1 = b;
    Derived& der1 = dynamic_cast<Derived&>(base1);
    der1.Show();

    //基類引用基類
    Base a;
    Base& base2 = a;
    try
    {
        Derived& der2 = dynamic_cast<Derived&>(base2);
    }
    catch(bad_cast)
    {
        cout << "bad_cast error!!" << endl;
    }
    system("pause");
}

This is Derived class
bad_cast error!!

4、reinterpret_cast

4.1 非關聯類型的轉換

操作結果是一個指針到其他指針的二進制拷貝,沒有類型檢查。

總結

原文鏈接:https://blog.csdn.net/qq_42301196/article/details/128839038

欄目分類
最近更新