C++之運行時類型識別RTTI


 C++ Code 
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  /*
    名稱:C++ 運行時類型識別
    作者:Michael Joessy
    日期:2017-06-06
    知識:Run-Time Type Information
    通過運行時類型信息程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。
    typeid  dynamic_cast
    注意:
    dynamic_cast:
        只能用於指針和引用的轉換;
        要轉換的類型中必須包含虛函數;
        轉換成功返回子類的地址,失敗返回NULL.
    typeid:
        typeid返回一個type_info(#include <typeinfo>)對象的引用;
        如果想通過基類的指針獲得派生類的數據類型,基類必須帶有虛函數;
        只能獲取對象的實際類型.
*/


/*
    class type_info {
    public:
    virtual ~type_info();
    _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator==(const type_info& rhs) const;
    _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator!=(const type_info& rhs) const;
    _CRTIMP_PURE int __CLR_OR_THIS_CALL before(const type_info& rhs) const;
    _CRTIMP_PURE const char* __CLR_OR_THIS_CALL name(__type_info_node* __ptype_info_node = &__type_info_root_node) const;
    _CRTIMP_PURE const char* __CLR_OR_THIS_CALL raw_name() const;
    private:
    void *_m_data;
    char _m_d_name[1];
    __CLR_OR_THIS_CALL type_info(const type_info& rhs);
    type_info& __CLR_OR_THIS_CALL operator=(const type_info& rhs);
    _CRTIMP_PURE static const char *__CLRCALL_OR_CDECL _Name_base(const type_info *,__type_info_node* __ptype_info_node);
    _CRTIMP_PURE static void __CLRCALL_OR_CDECL _Type_info_dtor(type_info *);
    };
*/


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

class Flyable
{
public:
    
virtual void takeoff() = 0;   //起飛
    virtual void land() = 0;      //着陸
         
protected:
private:
};

class Bird : public Flyable
{
public:
    
void forageing()             //覓食
    {
        cout << 
"Bird->forageing()" << endl;
    }
    
virtual void takeoff()       //起飛
    {
        cout << 
"Bird->takeoff()" << endl;
    }
    
virtual void land()         //着陸 
    {
        cout << 
"Bird->land()" << endl;
    }
protected:
private:
};

class Plane : public Flyable
{
public:
    
void carry()                 //運輸
    {
        cout << 
"Plane->carry()" << endl;
    }
    
virtual void takeoff()       //起飛
    {
        cout << 
"Plane->takeoff()" << endl;
    }
    
virtual void land()          //着陸
    {
        cout << 
"Plane->land()" << endl;
    }
protected:
private:
};

void doSomething(Flyable* pObj)
{
    cout << 
typeid(*pObj).name() << endl;
    pObj->takeoff();
    
if (typeid(*pObj) == typeid(Bird))
    {
        Bird* pBird = 
dynamic_cast<Bird*>(pObj);
        
if (pBird)
        {
            pBird->forageing();
        }
    }
    
if (typeid(*pObj) == typeid(Plane))
    {
        Plane* pPlane = 
dynamic_cast<Plane*>(pObj);
        
if (pPlane)
        {
            pPlane->carry();
        }
    }
    pObj->land();
}

int main(void)
{
    Flyable* pObj1 = 
new Bird;
    Flyable* pObj2 = 
new Plane;
    doSomething(pObj1);
    doSomething(pObj2);

    
/************************************************************************/
    
/* typeid usage                                           
    /************************************************************************/

    
int nNumber = 23;
    cout << 
typeid(nNumber).name() << endl;

    Flyable* p = 
new Bird;
    cout << 
typeid(p).name() << endl;
    cout << 
typeid(*p).name() << endl;

    cin.get();
    
return 0;
}

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: