<kbd id="daqct"></kbd>

  • <nav id="daqct"></nav>
    <wbr id="daqct"><pre id="daqct"></pre></wbr>
    <wbr id="daqct"></wbr>
    <form id="daqct"><th id="daqct"></th></form>
    更多課程 選擇中心

    C/C++培訓
    達內IT學院

    400-111-8989

    教你如何用C++創建一個特殊的類

    • 發布:C++培訓
    • 來源:學習筆記
    • 時間:2017-04-18 16:23

        就語言而言,個人還是比較喜歡C++,盡管 C++有些語法方面確實比較深奧,但這些確實擋不住它在實際應用中不可被替代的位置。

        開始談今天的重點,如何定義一個特殊的C++類。

    1、定義不可被繼承的C++類

        如何讓一個類不能被繼承呢?簡單來說,我們希望達到的效果,就是如果繼承這個類的話,編譯直接報錯。

        實現這個類,我希望你提前了解過以下幾個C++的簡單語法:友元類虛繼承這里我直接告訴你如何來定義,接下來我們討論為什么。

        第一步:定義一個空類A,顯式給出構造和析構構造和析構必須定義為private。

        第二步:定義不可被繼承的類B,給出正常的構造和析構,public類型,讓 B虛繼承A類繼承方式不限,同時將B設置為A的友元類

        第三步:定義類C去嘗試虛擬繼承類B,編譯錯誤! 

    代碼如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class A
    {
        friend class B;
    private:
        A(){}
        ~A(){}
    };
     
    class B:virtual public A
    {
    public:
        B()
        {}
    };
     
    class C :public B
    {
    public:
        C()
        {}
    };


    我們來討論,為什么編譯會出錯?

        首先,將類A的構造函數和析構函數定義為私有,如果沒有顯示定義,默認的構造和析構函數是public的。那定義為protected類型可以嗎?答案是“NO”。了解過繼承的話,應該知道,基類中private類型的成員變量或方法,在所有派生類中是不可見,但protected類型的成員變量或方法是可見的。我們的目的是如果以后構造類A的派生類時,需要調用類A構造,必須在類A內部調用該方法,即使是派生類,我也希望它遵守,即對派生類不可見

        其次,類B繼承了類A,繼承方式無所謂,因為基類私有部分不論以何種方式繼承,都是不可見的。為什么要虛繼承呢?這個稍后說。同時,類B這里定義成類A的友元類,那么以后類B就可以直接訪問類A的私有成員了,也就是說,這里的友元,打破了我們一開始定義的對派生類不可見的限制。那么以后在使用類B實例化對象時,完全可以成功,構造基類部分是通過友元實現的,和繼承方式無關。這里的類B就是我們定義的不可被繼承的類。

        最后,我們嘗試讓類C繼承類B,那么當類C實例化對象時(或顯式定義了構造函數),就會首先去構造屬于類B的部分。這里注意,如果類B不是虛繼承類A的話,那么這里構造屬于類B的部分時,是通過類B構造類A部分,這必然是成功的。但我們不希望,因此,這里類B虛繼承了類A,當構造屬于類B部分時,由于B虛繼承了A,那么會由類C直接去訪問A,嘗試構造類A的部分,很明顯,由于訪問不到類A的構造函數,因此C實例化對象失敗。之后,所有嘗試繼承類B的類都會在編譯時失敗(前提要求C顯示給出了構造,或類C實例化了對象)。

        到這里,不可被繼承了類B創建成功,這里很巧妙的應用了友元類的概念,從而實現了僅有B可以實例化屬于A的部分。


        如果覺得這種方式太過靈活,不容易理解,那么還有一種更加簡單的方式。C++11引入了final關鍵字,被該關鍵字修飾的類,都是不可被繼承的,這個和java中的用法基本是一致的。

    1
    2
    3
    4
    5
    6
    7
    8
    class A final
    {
    public:
        A(){}
    };
     
    class B :public A        // 編譯出錯
    {};

    2、定義一個只可以在棧上創建對象的類

        如果上面那種情況理解的話,這里應該不會太難。為什么只可以在棧上創建對象?如何實現?其實很簡單,只要我們只對外暴露出可以在堆上創建對象的接口就可以。代碼如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    class A
    {
    public:
        static A* Get_A(int x)
        {
            return new A(x);
        }
        static void Delete_A(A* a)
        {
            delete a;
        }
    private:
        A(int a = 10)
            :_a(a)
        {}
    private:
        int _a;
    };
     
    int main()
    {
        A* pa = A::Get_A(9);
        A* pb = A::Get_A(7);
        return 0;
    }

        和之前一樣,將構造函數和析構函數都設置為私有(因為這里不涉及繼承,private和protected在這里沒有區別),由于構造函數都是私有的,無法創建對象,因此,提供了靜態方法,該方法中通過new和delete實現了在堆上對象的獲取和釋放。


    3、定義一個只可以在棧上創建對象的類

        如果理解了上一種,就應該知道這里該如何去做。只要我們只提供在棧上獲取對象的方式即可,由于棧空間是由操作系統維護了,沒有特殊需要,析構函數就沒有必要顯式給出,代碼如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class A
    {
    public:
        static A Get_A(int x)
        {
            return A(x);
        }
    private:
        A(int a = 10)
            :_a(a)
        {}
    private:
        int _a;
    };
     
    int main()
    {
        A pa = A::Get_A(9);
        A pb = A::Get_A(7);
        return 0;
    }

         只能在棧上或者只能在堆上創建的對象,實現起來原理是一樣的,類的構造和析構函數都設置為私有,當我的接口函數提供的方法是從堆中創建的對象時,類就只能在堆上創建對象,當我的接口函數提供的是從棧上直接得到的對象的話,類就只可以在棧上創建對象。需要注意一點的是,創建棧上對象的時候,不可以返回臨時對象的引用,這個就不再多解釋。


    預約申請免費試聽課

    填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

    上一篇:C語言學習網站和C語言學習書籍推薦
    下一篇:C語言入門學習和書籍推薦

    C語言創建windows窗口實例

    C++回調函數是什么?

    C++ shared_ptr和動態數組

    C語言有哪些關鍵詞,C語言44個關鍵詞大全

    • 掃碼領取資料

      回復關鍵字:視頻資料

      免費領取 達內課程視頻學習資料

    • 視頻學習QQ群

      添加QQ群:1143617948

      免費領取達內課程視頻學習資料

    Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

    選擇城市和中心
    黑龍江省

    吉林省

    河北省

    湖南省

    貴州省

    云南省

    廣西省

    海南省

    欧美三级片,白洁外传,第四色播日韩AV第一页,啪啪免费观看大全av 百度 好搜 搜狗
    <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>