自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++ 運(yùn)行時(shí)類型信息與繼承技巧探索

開發(fā) 前端
C++中確實(shí)有一些特性提供了對(duì)對(duì)象的運(yùn)行時(shí)視圖。這些特性通常被歸為一組功能,稱為運(yùn)行時(shí)類型信息(RTTI)。

運(yùn)行時(shí)類型特性

相比于其他面向?qū)ο笳Z言,C++更傾向于編譯時(shí)處理。如你之前所學(xué),重寫方法之所以有效,是因?yàn)榉椒ㄅc其實(shí)現(xiàn)之間存在一層間接關(guān)系,而不是因?yàn)閷?duì)象內(nèi)置了對(duì)其所屬類的知識(shí)。然而,C++中確實(shí)有一些特性提供了對(duì)對(duì)象的運(yùn)行時(shí)視圖。這些特性通常被歸為一組功能,稱為運(yùn)行時(shí)類型信息(RTTI)。

RTTI提供了許多有用的特性,用于處理對(duì)象的類成員信息。其中一個(gè)特性是 dynamic_cast(),它允許你在面向?qū)ο蟮膶哟谓Y(jié)構(gòu)中安全地在類型之間轉(zhuǎn)換;這在本章前面已經(jīng)討論過。在沒有虛表(即沒有虛方法)的類上使用 dynamic_cast() 會(huì)導(dǎo)致編譯錯(cuò)誤。

有趣且不尋常的繼承問題

RTTI的第二個(gè)特性是 typeid 運(yùn)算符,它允許你在運(yùn)行時(shí)查詢對(duì)象的類型。大多數(shù)情況下,你不應(yīng)該需要使用 typeid,因?yàn)榛趯?duì)象類型有條件地運(yùn)行的代碼最好通過虛方法處理。以下代碼使用 typeid 根據(jù)對(duì)象的類型打印消息:

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;
    }
}

每當(dāng)你看到這樣的代碼時(shí),你應(yīng)該立即考慮使用虛方法重新實(shí)現(xiàn)功能。在這種情況下,更好的實(shí)現(xiàn)方式是在 Animal 類中聲明一個(gè)名為 speak() 的虛方法。Dog 類重寫該方法以打印 "Woof!",而 Bird 類重寫該方法以打印 "Chirp!"。這種方法更符合面向?qū)ο缶幊痰乃枷?,即將與對(duì)象相關(guān)的功能賦予這些對(duì)象。

警告:typeid 運(yùn)算符只有在類至少有一個(gè)虛方法時(shí)才能正確工作,即當(dāng)類有虛表時(shí)。此外,typeid 運(yùn)算符會(huì)從其參數(shù)中去除引用和常量修飾符。typeid 運(yùn)算符可能對(duì)于日志記錄和調(diào)試目的有用。以下代碼展示了如何使用 typeid 進(jìn)行日志記錄。logObject() 函數(shù)接受一個(gè)可記錄的對(duì)象作為參數(shù)。這種設(shè)計(jì)使得任何可以被記錄的對(duì)象都繼承自 Loggable 類,并支持一個(gè)名為 getLogMessage() 的方法。


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."; } };

繼承技巧的發(fā)現(xiàn)

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() 函數(shù)首先將對(duì)象類的名稱寫入輸出流,然后是其日志消息。這樣,當(dāng)你稍后閱讀日志時(shí),你可以看到每條寫入的行是由哪個(gè)對(duì)象負(fù)責(zé)的。以下是使用 Microsoft Visual C++ 2019 編譯并調(diào)用 logObject() 函數(shù)時(shí)生成的輸出示例:

class Foo: Hello logger.

如你所見,由 typeid 運(yùn)算符返回的名稱是 “class Foo”。然而,這個(gè)名稱依賴于你使用的編譯器。例如,如果你使用 GCC 編譯相同的代碼,輸出將如下所示:

3Foo: Hello logger.

注意:如果你使用 typeid 進(jìn)行的目的不是日志記錄和調(diào)試,請(qǐng)考慮使用虛方法重新實(shí)現(xiàn)它。

責(zé)任編輯:趙寧寧 來源: coding日記
相關(guān)推薦

2024-12-09 13:00:00

C++類型安全

2011-08-19 15:05:29

異常處理

2010-01-27 14:14:48

C++程序運(yùn)行時(shí)間

2025-03-03 09:10:00

C++開發(fā)

2022-12-30 08:08:30

2015-07-20 15:44:46

Swift框架MJExtension反射

2024-03-21 09:15:58

JS運(yùn)行的JavaScrip

2011-12-27 09:39:12

C#運(yùn)行時(shí)

2024-01-08 08:24:02

PythonSys 模塊工具

2009-09-24 17:19:06

運(yùn)行時(shí)多態(tài)性

2020-09-28 15:54:18

Python語言技術(shù)

2018-06-24 15:23:05

軟件工程環(huán)境開發(fā)

2019-07-12 09:30:12

DashboardDockerDNS

2021-09-11 15:38:23

容器運(yùn)行鏡像開放

2009-02-10 09:03:59

動(dòng)態(tài)語言CLRVB.NET

2025-03-28 01:00:00

Go語言版本

2021-08-18 08:32:09

代碼運(yùn)行時(shí)間示波器

2013-11-26 16:49:55

Android開發(fā)運(yùn)行時(shí)KitKat

2020-12-07 13:31:43

GoMutex開發(fā)者

2023-01-03 09:10:21

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)