首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 基礎

C++ typeid 運算符詳解:運行時類型識別 (RTTI) 核心機制

     編輯:C++ 基礎

typeid 核心功能

typeid 用於獲取表達式或類型的類型信息,返回 const type_info&。類型信息包含:基本型別的名稱、類型別的類關係、成員、繼承體系等。

兩種使用形式

typeid(類型名)      // 如 typeid(int), typeid(MyClass)
typeid(表達式)      // 如 typeid(x), typeid(*ptr), typeid(a+b)

類似 sizeof,但必須帶括號。需包含 <typeinfo>。

type_info 核心成員函數

函數功能標準規定
name()返回類型名稱字串實現定義(MSVC: "class Base", GCC: "4Base")
raw_name()返回修飾名MSVC 專有
hash_code()返回類型雜湊值C++11 標準
before()類型順序比較實現定義,無語義保證
operator==/!=類型相等/不等判斷標準要求

實戰範例與跨平台差異

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {};
struct STU {};

int main() {
    int n = 100;
    const type_info& nInfo = typeid(n);
    cout << nInfo.name() << " | " << nInfo.raw_name() << " | " << nInfo.hash_code() << endl;

    const type_info& dInfo = typeid(25.65);
    cout << dInfo.name() << " | " << dInfo.raw_name() << " | " << dInfo.hash_code() << endl;

    Base obj;
    cout << typeid(obj).name() << " | " << typeid(obj).hash_code() << endl;
    cout << typeid(Base).name() << " | " << typeid(Base).hash_code() << endl;
    cout << typeid(STU).name() << " | " << typeid(STU).hash_code() << endl;
    cout << typeid(char).name() << " | " << typeid(char).hash_code() << endl;
    cout << typeid(20 * 45 / 4.5).name() << " | " << typeid(20 * 45 / 4.5).hash_code() << endl;
}

MSVC 輸出

int | .H | 529034928
double | .N | 667332678
class Base | .?AVBase@@ | 1035034353
class Base | .?AVBase@@ | 1035034353
struct STU | .?AUSTU@@ | 734635517
char | .D | 4140304029
double | .N | 667332678

GCC 輸出差異

i | (null) | 123456
d | (null) | 789012
4Base | (null) | 345678
4Base | (null) | 345678
4STU | (null) | 901234
c | (null) | 567890
d | (null) | 789012

關鍵結論:name() 返回值高度依賴實現,不可跨平台依賴具體字串格式。

核心應用:類型相等判斷

基本型別比較

char* str; int a=2, b=10; float f;

typeid(int) == typeid(int)        // true
typeid(int) == typeid(char)       // false
typeid(str) == typeid(char*)      // true
typeid(a) == typeid(b)            // true (同類型)
typeid(a/b) == typeid(int)        // true (整數除法結果為 int)

同一類型在程式中僅有一個 type_info 物件,所有 typeid 返回其引用。

類型別與指針比較

class Base {}; class Derived : public Base {};
Base obj1, *p1; Derived obj2, *p2 = new Derived;
p1 = p2;  // 基類指針指向派生物件

typeid(obj1) == typeid(p1)        // false (Base vs Base*)
typeid(obj1) == typeid(*p1)       // true  (Base vs Base)
typeid(&obj1) == typeid(p1)       // true  (Base* vs Base*)
typeid(obj1) == typeid(obj2)      // false (Base vs Derived)
typeid(obj1) == typeid(Base)      // true
typeid(*p1) == typeid(Base)       // true  // 關鍵:靜態類型為 Base
typeid(p1) == typeid(Base*)       // true
typeid(p1) == typeid(Derived*)    // false

重要:typeid(*p1) 取決於指針靜態類型(此處為 Base*),而非動態類型。要獲取動態類型需配合 virtual 函數(RTTI 完整機制見後續章節)。

type_info 類聲明剖析

class type_info {
public:
    virtual ~type_info();
    bool operator==(const type_info&) const;
    bool operator!=(const type_info&) const;
    bool before(const type_info&) const;
    const char* name() const;
    const char* raw_name() const;  // MSVC 擴展
private:
    void* _m_data;
    char _m_d_name[1];
    type_info(const type_info&);           // 禁止拷貝
    type_info& operator=(const type_info&); // 禁止賦值
};
  • 構造/賦值為 private:只能由編譯器內部建構
  • 虛析構:支援多態銷毀

效能與限制

  • 編譯器優化:僅為使用 typeid 的類型生成 type_info,含虛函數的類除外(必須生成)
  • 功能有限:對比 Java/C# 反射極弱,無成員枚舉、動態構造等
  • 主要用途:類型相等判斷、簡單診斷日誌、RTTI 基礎

總結

typeid 是 C++ RTTI 的入口,提供基礎類型查詢能力。但跨平台名稱不一致、功能極弱、僅支援靜態類型查詢(除非配合虛函數)。實務中主要用於 typeid(a) == typeid(b) 類型比對,複雜反射需求建議使用第三方庫或編譯期元程式技術。

  1. 上一篇文章:
  2. 下一篇文章:
  • --热点文章
  • Copyright © 程式碼之家 All Rights Reserved