type_info类,RTTI

一:RTTI
RTTI:Run Time Type Identification,运行时类型识别。
通过RTTI,程序能够使用基类的指针或者引用来检查这些指针或者引用所指的对象的实际派生类型。

理解:RTTI我们可以把这个称呼看成是一种系统提供给我们的一种能力,或者一种功能。
这种功能或者能力是通过两个运算符来体现的。

(1)dynamic_cast运算符,能够将基类的指针或者引用安全的转换为派生类的指针或者引用。
(2)typeid运算符,返回指针或者引用所指对象的实际类型。

说明:要想让RTTI工作,则父类当中必须要有虚函数。

RTTI实现原理
vs2019测试

class A
{
public:
	A() {};
	virtual ~A() {}
	int a;
};

A* obj = new A();
long* p1 = (long*)obj;
long* p2 = (long *)*p1;
long* p3 = (long *)(*(p2 - 1));
long* p4 = (long*)(*(p3 + 3));
const std::type_info* p5 = (const std::type_info *) p4;
cout << p5->name() << endl; //class A

二:type_info类与dynamic_cast运算符

(1)dynamic_cast运算符

class A
{
public:
	A() {};
	virtual ~A() {}
};

class B :public A
{
public:
	void aaa() {}
};

A* a = new B();
B* obj = dynamic_cast<B*>(a);
if (obj != nullptr)
{
   printf("转换成功");
}
else
{
   printf("转换失败");
}

/*引用方面的转换*/
A& q = *a;
try
{
	B& b = dynamic_cast<B &> (q);
	printf("转换成功");
}
catch (std::bad_cast)
{
	/**/
	printf("转换失败");
}

//转换成功了,我们就可以调用类B里面定义的函数了,不然的话,虽然new的是B,但是,还是会调用不了类B里面的非虚函数,所以说,既不想把函数声明成虚函数的话,但是又想调用类B的函数的话,就需要dynamic_cast运算符运算符了。

(2)typeid运算符

#include <iostream>
#include <string>
using namespace std;
class A {
public:
    int a;
    virtual void bb(){}
};
class B:public A {
public:
    void b()
    {
    }
};
int main()
{
    //typeid运算符
    //typeid(表达式) typeid(类型) 
    A obj;
    std::cout << typeid("a").name() << std::endl;
    std::cout << typeid(obj).name() << std::endl;
    std::cout << typeid(int).name() << std::endl;
    A* p = new B();
    A* q = new A();
    //比较指针的类型是否相同,
    if (typeid(p) == typeid(q)) {
        std::cout << "p和q的静态类型相同" << std::endl;
    }
    if (typeid(*p) == typeid(*q)) {
        std::cout << "p和q的动态类型相同" << std::endl;
    }
    return 0;
}

(2)type_info类

#include <iostream>
#include <string>
using namespace std;
class A {
public:
    int a;
    virtual void bb(){}
};
class B:public A {
public:
    void b()
    {
    }
};

int main()
{
   //typeid,返回的是一个常量对象的引用,这个常量对象是标准库当中的type_info类
    A* p = new B();
    A* q = new B();
    const std::type_info& tp = typeid(*p);
    const std::type_info& tp1 = typeid(*q);
    //有虚函数,所以类型是B,如果没有虚寒苏,类型就是A
    std::cout << tp.name() << std::endl;
    //type_info还支持类型比较
    if (tp == tp1) {
        std::cout << "tp和tp1的动态类型相同" << std::endl;
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值