日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

C++ 運行時類型信息與繼承技巧探索

來源: 責編: 時間:2023-11-21 17:12:50 215觀看
導讀運行時類型特性相比于其他面向對象語言,C++更傾向于編譯時處理。如你之前所學,重寫方法之所以有效,是因為方法與其實現之間存在一層間接關系,而不是因為對象內置了對其所屬類的知識。然而,C++中確實有一些特性提供了對對象

運行時類型特性

相比于其他面向對象語言,C++更傾向于編譯時處理。如你之前所學,重寫方法之所以有效,是因為方法與其實現之間存在一層間接關系,而不是因為對象內置了對其所屬類的知識。然而,C++中確實有一些特性提供了對對象的運行時視圖。這些特性通常被歸為一組功能,稱為運行時類型信息(RTTI)。H9W28資訊網——每日最新資訊28at.com

RTTI提供了許多有用的特性,用于處理對象的類成員信息。其中一個特性是 dynamic_cast(),它允許你在面向對象的層次結構中安全地在類型之間轉換;這在本章前面已經討論過。在沒有虛表(即沒有虛方法)的類上使用 dynamic_cast() 會導致編譯錯誤。H9W28資訊網——每日最新資訊28at.com

H9W28資訊網——每日最新資訊28at.com

有趣且不尋常的繼承問題

RTTI的第二個特性是 typeid 運算符,它允許你在運行時查詢對象的類型。大多數情況下,你不應該需要使用 typeid,因為基于對象類型有條件地運行的代碼最好通過虛方法處理。以下代碼使用 typeid 根據對象的類型打印消息:H9W28資訊網——每日最新資訊28at.com

import <typeinfo>;class Animal { public: virtual ~Animal() = default; };class Dog : public Animal {};class Bird : public Animal {};void speak(const Animal& animal) {    if (typeid(animal) == typeid(Dog)) {        cout << "Woof!" << endl;    } else if (typeid(animal) == typeid(Bird)) {        cout << "Chirp!" << endl;    }}

每當你看到這樣的代碼時,你應該立即考慮使用虛方法重新實現功能。在這種情況下,更好的實現方式是在 Animal 類中聲明一個名為 speak() 的虛方法。Dog 類重寫該方法以打印 "Woof!",而 Bird 類重寫該方法以打印 "Chirp!"。這種方法更符合面向對象編程的思想,即將與對象相關的功能賦予這些對象。H9W28資訊網——每日最新資訊28at.com

警告:typeid 運算符只有在類至少有一個虛方法時才能正確工作,即當類有虛表時。此外,typeid 運算符會從其參數中去除引用和常量修飾符。typeid 運算符可能對于日志記錄和調試目的有用。以下代碼展示了如何使用 typeid 進行日志記錄。logObject() 函數接受一個可記錄的對象作為參數。這種設計使得任何可以被記錄的對象都繼承自 Loggable 類,并支持一個名為 getLogMessage() 的方法。H9W28資訊網——每日最新資訊28at.com


H9W28資訊網——每日最新資訊28at.com

H9W28資訊網——每日最新資訊28at.com

class Loggable { public: virtual ~Loggable() = default; virtual std::string getLogMessage() const = 0; };class Foo : public Loggable { public: std::string getLogMessage() const override { return "Hello logger."; } };

繼承技巧的發現

class Loggable {public:    virtual ~Loggable() = default;    virtual std::string getLogMessage() const = 0;};class Foo : public Loggable {public:    std::string getLogMessage() const override {        return "Hello logger.";    }};void logObject(const Loggable& loggableObject) {    cout << typeid(loggableObject).name() << ": ";    cout << loggableObject.getLogMessage() << endl;}

logObject() 函數首先將對象類的名稱寫入輸出流,然后是其日志消息。這樣,當你稍后閱讀日志時,你可以看到每條寫入的行是由哪個對象負責的。以下是使用 Microsoft Visual C++ 2019 編譯并調用 logObject() 函數時生成的輸出示例:H9W28資訊網——每日最新資訊28at.com

class Foo: Hello logger.

如你所見,由 typeid 運算符返回的名稱是 “class Foo”。然而,這個名稱依賴于你使用的編譯器。例如,如果你使用 GCC 編譯相同的代碼,輸出將如下所示:H9W28資訊網——每日最新資訊28at.com

3Foo: Hello logger.

注意:如果你使用 typeid 進行的目的不是日志記錄和調試,請考慮使用虛方法重新實現它。H9W28資訊網——每日最新資訊28at.com

H9W28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-32428-0.htmlC++ 運行時類型信息與繼承技巧探索

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: FreeBSD 14 系統正式版發布:支持 1024 個 CPU 內核,下版本放棄 32 位硬件

下一篇: 低代碼開發平臺,是技術創新還是束縛?

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 沅江市| 凭祥市| 灵武市| 富锦市| 突泉县| 清苑县| 睢宁县| 贵德县| 响水县| 静乐县| 丹棱县| 德庆县| 汝阳县| 体育| 商水县| 玉门市| 长葛市| 青铜峡市| 县级市| 西乌珠穆沁旗| 柳林县| 邹平县| 仪征市| 哈尔滨市| 松溪县| 娄底市| 大兴区| 彰化市| 阜康市| 略阳县| 大方县| 英山县| 平邑县| 麟游县| 蒙山县| 余江县| 安国市| 汶上县| 钟山县| 博乐市| 海兴县|