RTTI —— 运行阶段类型识别

RTTI —— 运行阶段类型识别

1.多态

  • 定义:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。
  • 无多态性示例
class Base
{
public:
    Base(){}
    void FunOne(){std::cout << "This is Base" << std::endl;}
};

class SubOne : public Base
{
public:
    SubOne(){}
    void FunOne(){std::cout << "This is SubOne" << std::endl;}
};

运行结果:
在这里插入图片描述
2.多态性示例

class Base
{
public:
    Base(){}
    virtual ~Base() {}
    virtual void FunOne(){std::cout << "This is Base" << std::endl;}
};

class SubOne : public Base
{
public:
    SubOne(){}
    ~SubOne()override {}
    void FunOne() override {std::cout << "This is SubOne" << std::endl;}
};

运行结果:
在这里插入图片描述

2.运行阶段类型识别

运行阶段类型识别运用于继承时需要派生类具有多态性 <==> 必须实现一个或多个虚函数

1.dynamic_cast

功能:将指向派生类对象的父类指针转换为派生类指针,转换失败返回nullptr
使用示例:

int main()
{
    Base *pBase = new Base;
    Base *pSub = new SubOne;
    SubOne *pSub2 = new SubOne;
    
    SubOne *pDyname1 = dynamic_cast<SubOne*>(pSub);
    if(nullptr == pDyname1)
    {
        std::cout << "pDyname1 dynamic_cast fail" << std::endl;
    }
    else
    {
        std::cout << "pDyname1 dynamic_cast success" << std::endl;
    }

    SubOne *pDyname2 = dynamic_cast<SubOne*>(pBase);
    if(nullptr == pDyname2)
    {
        std::cout << "pDyname2 dynamic_cast fail" << std::endl;
    }
    else
    {
        std::cout << "pDyname2 dynamic_cast success" << std::endl;
    }
}

运行结果:
在这里插入图片描述

2.typeid和type_info

typeid运算符返回一个type_info类型的对象的引用,typeid可以应用于任何类型或具有该类型的任何表达式。
type_info类头文件为#include <typeinfo.h>,此类重载了 != 和 == 一般会实现name()函数返回一个随实现而不同的字符串。c++中还实现了before();原型如下:

const char* name() const;
//可用于判断继承类型
bool before (const type_info& rhs) const;

使用示例:

int main()
{
    double dbParam = 2.2;
    int iParam = 1;
    Base *pNull = nullptr;
    Base *pBase = new Base;
    Base *pSub = new SubOne;
    SubOne *pSub2 = new SubOne;

    if(typeid (double) == typeid (dbParam))
    {
        std::cout << "dbParam is double type" << "\tname = " << typeid (dbParam).name() << std::endl;
    }
    if(typeid (int) == typeid (dbParam))
    {
        std::cout << "dbParam is int type" << "\tname = " << typeid (dbParam).name() << std::endl;
    }

    if(typeid (double) == typeid (iParam))
    {
        std::cout << "iParam is double type" << "\tname = " << typeid (iParam).name() << std::endl;
    }
    if(typeid (int) == typeid (iParam))
    {
        std::cout << "iParam is int type" << "\tname = " << typeid (iParam).name() << std::endl;
    }

    //----------------------------------------------------------------------
    if(typeid (Base).before(typeid (SubOne)))
    {
        std::cout << "SubOne after Base" << std::endl;
    }
    else
    {
        std::cout << "SubOne before Base" << std::endl;
    }

    //----------------------------------------------------------------------
    if(typeid (Base) == typeid (*pBase))
    {
        std::cout << "*pBase is Base type" << "\tname = " << typeid (*pBase).name() << std::endl;
    }
    if(typeid (SubOne) == typeid (*pBase))
    {
        std::cout << "*pBase is SubOne type" << "\tname = " << typeid (*pBase).name() << std::endl;
    }

    if(typeid (Base*) == typeid (pBase))
    {
        std::cout << "pBase is Base* type" << "\tname = " << typeid (pBase).name() << std::endl;
    }
    if(typeid (SubOne*) == typeid (pBase))
    {
        std::cout << "pBase is SubOne* type" << "\tname = " << typeid (pBase).name() << std::endl;
    }

    //----------------------------------------------------------------------
    if(typeid (Base) == typeid (*pSub))
    {
        std::cout << "*pSub is Base type" << "\tname = " << typeid (*pSub).name() << std::endl;
    }
    if(typeid (SubOne) == typeid (*pSub))
    {
        std::cout << "*pSub is SubOne type" << "\tname = " << typeid (*pSub).name() << std::endl;
    }

    if(typeid (Base*) == typeid (pSub))
    {
        std::cout << "pSub is Base* type" << "\tname = " << typeid (pSub).name() << std::endl;
    }
    if(typeid (SubOne*) == typeid (pSub))
    {
        std::cout << "pSub is SubOne* type" << "\tname = " << typeid (pSub).name() << std::endl;
    }

    //----------------------------------------------------------------------
    if(typeid (Base) == typeid (*pSub2))
    {
        std::cout << "*pSub2 is Base type" << "\tname = " << typeid (*pSub2).name() << std::endl;
    }
    if(typeid (SubOne) == typeid (*pSub2))
    {
        std::cout << "*pSub2 is SubOne type" << "\tname = " << typeid (*pSub2).name() << std::endl;
    }

    if(typeid (Base*) == typeid (pSub2))
    {
        std::cout << "pSub2 is Base* type" << "\tname = " << typeid (pSub2).name() << std::endl;
    }
    if(typeid (SubOne*) == typeid (pSub2))
    {
        std::cout  << "pSub2 is SubOne* type" << "\tname = " << typeid (pSub2).name()<< std::endl;
    }

    //----------------------------------------------------------------------
    if(typeid (Base*) == typeid (pNull))
    {
        std::cout << "pNull is Base* type" << "\tname = " << typeid (pNull).name() << std::endl;
    }
    if(typeid (SubOne*) == typeid (pNull))
    {
        std::cout << "pNull is SubOne* type" << "\tname = " << typeid (pNull).name() << std::endl;
    }
    
    return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值