小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C 中廣泛使用的技術(shù)之模板元編程讓繼承作為一種技術(shù)工具

 山峰云繞 2018-08-07

前言

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

      【【C語言基礎(chǔ)】C ++中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具】https://toutiao.com/group/6586910869827895815/?iid=15906422033&app=explore_article&timestamp=1533652528&group_id=6586910869827895815&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share 




更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

C 是一種多范式語言,因此它不是純粹的面向?qū)ο笳Z言,而是具有其他方面,例如通過模板對通用編程的巨大支持。其主要優(yōu)勢之一是能夠混合這些不同方面。

繼承是C 中主要面向?qū)ο蟮姆矫嬷?,在純粹的面向?qū)ο蟮纳舷挛闹校馕吨癐s-A”關(guān)系。在與C 的其他方面的混合中,繼承可以用于純粹的技術(shù)和其他原因,這些原因并不意味著面向?qū)ο蟮淖宇愋汀?/p>

在本文中,我將探討在C 中繼承的可能用途。

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

面向?qū)ο?/strong>

我將假設(shè)以面向?qū)ο蟮姆绞绞褂美^承是充分已知的,因此我不會詳細(xì)介紹Liskov替換原則和該主題的其他一般方面。但是有一些方面與C#或Java等其他語言不同,所以我將在這里簡要介紹一下。

構(gòu)造函數(shù)和析構(gòu)函數(shù)中的虛函數(shù)

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

我假設(shè)您了解虛擬功能以及它們的工作原理。然而,對于許多C 開發(fā)人員而言,在構(gòu)造函數(shù)和析構(gòu)函數(shù)中使用虛函數(shù)令人驚訝。請考慮以下代碼:

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

許多人會期望打印字符串“Derived :: foo”,因為它是一個“Derived”對象,它被創(chuàng)建。但是如果你知道編譯器在構(gòu)造對象時做了什么,很明顯為什么不會發(fā)生這種情況:

構(gòu)造`Derived`對象時,首先要構(gòu)造該對象的`Base`部分。`Derived`對象尚未開始存在。作為“派生”對象的整個事物的身份在其所有部分(包括“Base”子對象已經(jīng)初始化)之后得到建立。因此當(dāng)調(diào)用`foo()`時,除了一個`Base`對象之外什么都沒有,因此可以調(diào)用的唯一`foo`是`Base :: foo`。

同樣的推理適用于析構(gòu)函數(shù)中的虛函數(shù)調(diào)用:`Base`析構(gòu)函數(shù)在`Derived`對象的所有其他部分都被銷毀后作為最后一步執(zhí)行,然后作為`Derived`的對象的身份已經(jīng)結(jié)束。

虛擬析構(gòu)函數(shù)

上面的`Base`類沒有正確編寫。根據(jù) Herb Sutter的這條規(guī)則,“Base”的析構(gòu)函數(shù)應(yīng)該是虛擬的或受保護(hù)的。虛擬,如果你想能夠在`Base`類指針上調(diào)用`delete`,包括使用`Base`智能指針,否則保護(hù)。

由于面向?qū)ο蟮睦^承通常與某種基類指針密切相關(guān),因此將析構(gòu)函數(shù)設(shè)置為public和virtual是正確的選擇。因此,考慮到 全部規(guī)則或無規(guī)則,“基礎(chǔ)”應(yīng)如下所示:

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

這看起來像是一個巨大的開銷,但是在最頂層的基類中聲明虛擬析構(gòu)函數(shù)就足夠了,任何派生類的析構(gòu)函數(shù)也將自動虛擬化。

多重繼承

除了允許類僅從單個其他類派生并且可能實現(xiàn)一個或多個接口的許多其他語言之外,C 允許實際的多重繼承。這意味著,允許一個類派生自多個完全成長的類,每個類都有自己的成員變量,虛擬和非虛函數(shù)等等。

這可能會導(dǎo)致一些問題,其中一些問題非常微妙且違反直覺。例如,如果兩個基類具有相同名稱的函數(shù),則在派生類中調(diào)用其中一個可能不明確。如果兩個基類派生自同一個類,則形成“致命的死亡之鉆”,這就是C 具有虛擬繼承的原因。

繼承作為一種技術(shù)工具

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

當(dāng)一個類派生自另一個類時,它不僅繼承了成員變量和方法,還繼承了該類的任何typedef和靜態(tài)成員。這可以在不同的場合使用。

模板元編程

C 中廣泛使用的技術(shù),特別是庫編寫者,是模板元編程。它通常涉及只包含typedef和常量定義的小類。通常這些類永遠(yuǎn)不會被實例化,即沒有創(chuàng)建它們的對象。

模板元編程中使用的許多類相互派生,以利用其基類中的常量和typedef的繼承,而不必重新定義它們。這類的示例是模板` std :: integral_constant`。它的兩個實例化,`std :: true_type`和`std :: false_type`它包含兩個typedef和一個靜態(tài)常量值,在這種情況下分別是`true`和`false`。

模板元函數(shù)的一個非常簡短的示例是一個小模板,用于確定unsigned int是偶數(shù)還是奇數(shù):

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

從通用實施細(xì)節(jié)中獲取

有時,有幾個類共享其實現(xiàn)的一些常見細(xì)節(jié)。將實現(xiàn)分解為所有這些類使用的另一個類是正常的。通常的選擇是使實用程序類的對象成為每個類的私有成員,但是實現(xiàn)者可能會選擇從實用程序類派生而來:

  • 如果實用程序類提供了派生類'接口的許多方法,則派生類必須實現(xiàn)轉(zhuǎn)發(fā)函數(shù)。
  • 如果實用程序類不是由派生類的實現(xiàn)者維護(hù)并包含受保護(hù)的函數(shù),則實現(xiàn)者需要訪問。
  • 空基類優(yōu)化。如果實用程序類沒有非靜態(tài)成員且沒有虛函數(shù),則它不包含實際數(shù)據(jù),即不需要占用任何空間。由于不同的原因,類的成員總是需要占用幾個字節(jié),但基類不需要它。因此,許多編譯器優(yōu)化了空基類占用的空間,使對象有效地變小。當(dāng)然,只有在給出這種優(yōu)化的需要時才應(yīng)該使用它。(注意:請參閱下面的注釋,如何在成員變量上使用EBO而不是類本身)。

奇怪的重復(fù)模板模式

所述CRTP是模板和繼承在C 一起工作的另一個例子。這意味著一個類派生自一個僅使用派生類實例化的模板:

C   中廣泛使用的技術(shù)之模板元編程,讓繼承作為一種技術(shù)工具

更多C/C 學(xué)習(xí)資料,請私信我“代碼”,即可獲取

使用此技巧的最常見場合之一是靜態(tài)多態(tài):基類可以調(diào)用派生類的方法,而無需為它們定義虛擬原型。這些方法的調(diào)用可以比虛函數(shù)調(diào)用快一點。但是,兩個派生類沒有公共基類,因為它們派生自模板的兩個不同實例,它們是不同的類。

結(jié)論

在C 中有許多可以使用繼承的方法,其中許多方法并不意味著面向?qū)ο蟮摹癐s-A”關(guān)系。通??梢酝ㄟ^最頂層基類中的公共虛擬析構(gòu)函數(shù)來識別那些。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多