zoukankan      html  css  js  c++  java
  • RTTI

    --------------siwuxie095

       

       

       

       

       

       

       

    这里介绍一个高大上的名词:RTTI

       

       

       

       

       

       

    RTTI

       

       

    RTTI,即 Run-Time Type Identification

       

       

       

       

    C++ 中,也称为 运行时类型识别

       

       

       

       

    RTTI 的体现方式:

       

       

       

       

    看如下实例:

       

    定义一个 Flyable 类,其中有两个纯虚函数:takeoff() 和 land()

       

       

       

       

    再定义一个 Bird 类,它 public 的继承了 Flyable 类,并实现了 takeoff()

    和 land(),并拥有自己独有的函数:foraging(),即 觅食

       

       

       

       

    再定义一个 Plane 类,它 public 的继承了 Flyable 类,并实现了 takeoff()

    和 land(),并拥有自己独有的函数:carry(),即 运输

       

       

       

       

    在使用时:

       

       

       

    假设有这样一个函数:doSomething(),其参数是 Flyable 的一个

    指针,在函数体中可以使用 obj 去调用 takeoff() 和 land()

       

       

    再设想一下,如果能够对传入的指针再做进一步的判断,即:

       

    1)如果判断它是一个 Bird 的对象指针,就能使用指针去调用 觅食 的函数

       

    2)如果判断它是一个 Plane 的对象指针,就能使用指针去调用 运输 的函数

       

       

       

    如果想要做到上述判断,就要使用 RTTI 运行时类型识别

       

       

       

    typeid(*obj).name() 可以获得当前 obj 指针指向的实际的对象类型

       

    cout 可以将其打印出来,再通过 if 语句进行比对,比对完成后,

    就可以将 obj 通过 dynamic_cast 的方式将其转化成为 bird 的指针

       

    转化时要注意:dynamic_cast 后面跟两个尖括号,中间写上要转化

    的目标类型

       

       

       

    总结:

       

    关于 dynamic_cast 的注意事项:

       

       

       

    1)只能应用与指针和引用的转换,即 只能转化为 某一个类型的

    指针 某一个类型的引用,而不能是 某类型本身

       

    2)要转化的类型中必须包含虚函数,如果没有虚函数,转换就会失败

       

    3)如果转换成功,返回子类的地址,如果转换失败,返回 NULL

       

       

       

    关于 typeid 的注意事项:

       

       

       

    1)typeid 返回一个 type_info 的对象引用

       

    2)如果想通过基类的指针指向派生类的数据类型,基类

    就必须要带有虚函数,否则,在使用 typeid 时,就只能返

    回定义时所使用的数据类型

       

    3)typeid 只能获取对象的实际类型,即便这个类含有虚

    函数,也只能判断当前对象是基类还是派生类,而不能判断

    当前指针是基类还是派生类

       

       

       

    type_info 中的内容:

       

       

       

    在上例中,typeid(*obj) 获取到的就是一个 type_info 的引用,通过

    该引用就能调用 type_info 中的 name() 函数

       

    type_info 中的 bool operator==(const type_info& rhs) const;

    运算符重载,通过它就可以进行两个 type_info 对象的比对

       

       

       

       

    程序:

       

    Flyable.h:

       

    #ifndef FLYABLE_H

    #define FLYABLE_H

       

    #include <iostream>

    using namespace std;

       

       

    //接口类

    class Flyable

    {

    public:

    virtual void takeoff() = 0;

    virtual void land() = 0;

    };

       

    #endif

       

       

       

    Bird.h:

       

    #ifndef BIRD_H

    #define BIRD_H

       

    #include "Flyable.h"

       

    class Bird:public Flyable

    {

    public:

    void foraging();

    virtual void takeoff();

    virtual void land();

    };

       

    #endif

       

       

       

    Bird.cpp:

       

    #include "Bird.h"

       

    void Bird::foraging()

    {

    cout << "Bird--foraging" << endl;

    }

       

    void Bird::takeoff()

    {

    cout << "Bird--takeoff" << endl;

    }

       

    void Bird::land()

    {

    cout << "Bird--land" << endl;

    }

       

       

       

    Plane.h:

       

    #ifndef PLANE_H

    #define PLANE_H

       

    #include "Flyable.h"

       

    class Plane:public Flyable

    {

    public:

    void carry();

    virtual void takeoff();

    virtual void land();

    };

       

    #endif

       

       

       

    Plane.cpp:

       

    #include "Plane.h"

       

    void Plane::carry()

    {

    cout << "Plane--carry" << endl;

    }

       

    void Plane::takeoff()

    {

    cout << "Plane--takeoff" << endl;

    }

       

    void Plane::land()

    {

    cout << "Plane--land" << endl;

    }

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "Bird.h"

    #include "Plane.h"

       

    void doSomething(Flyable *obj);

       

    int main(void)

    {

    Bird b;

    Plane p;

    doSomething(&b);

    cout << endl;

    doSomething(&p);

       

    //typeid的验证

    /*cout << endl;

    int i = 0;

    cout << typeid(i).name() << endl;

    Flyable *t = new Bird();

    cout << typeid(t).name() << endl;

    cout << typeid(*t).name() << endl;*/

       

    system("pause");

    return 0;

    }

       

    void doSomething(Flyable *obj)

    {

    //通过typeid获取到type_info的一个引用

    //通过引用调用name()成员函数 返回数据类型

    //

    //这里打印的是数据类型 传入的不是obj指针 而是对象*obj

    cout << typeid(*obj).name() << endl;

       

    obj->takeoff();

     

    //两个type_info对象的比对 运算符重载

    if (typeid(*obj) == typeid(Bird))

    {

    //转化为Bird的指针

    Bird *bird = dynamic_cast<Bird *>(obj);

    bird->foraging();

    }

    if (typeid(*obj)==typeid(Plane))

    {

    Plane *plane = dynamic_cast<Plane *>(obj);

    plane->carry();

    }

    obj->land();

    }

       

    //RTTI: Run-Time Type Identification 运行时类型识别

    //RTTI 的体现方式:typeid dynamic_cast

    //

    //dynamic_cast后面跟2个尖括号 <> dynamic<> 里面填上要转化的目标类型

    //

    //dynamic_cast注意事项:

    //1)只能应用于指针和引用的转换

    //2)要转换的类型必须包含虚函数

    //3)转换成功返回子类的地址,失败返回NULL

    //

    //typeid注意事项:

    //1typeid返回一个type_info对象的引用

    //2)如果想要通过基类的指针获得派生类的数据类型,基类必须带有虚函数

    //3)只能获取对象的实际类型

    //(判断当前对象属于基类还是派生类 只能判断对象不能判断指针)

    //

    //关于type_info,如下:

    //class type_info

    //{

    //public:

    // //name()函数

    // const char* name() const;

    // //运算符重载

    // bool operator==(const type_info& rhs) const;

    // bool operator!=(const type_info& rhs) const;

    // int before(const type_info& rhs) const;

    // virtual ~type_info();

    //private:

    // ....

    //};

       

       

    运行一览:

       

       

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    Mac安装zookeeper
    征途
    vue-配置文件
    数组去重
    判断身份证
    判断邮箱
    判断手机号是否正确
    JS 时间格式转换
    打印 print-js
    自"愚"自乐的云服务器
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6810827.html
Copyright © 2011-2022 走看看