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

原文地址:https://www.cnblogs.com/MakeView660/p/6950057.html