持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
type_info对象
C++提供了一个type_info类来获取对象类型信息:
-
这个类的构造函数是private的,因此用户不能直接构造这样的对象,只能通过typeid()函数来获取这个对象.
-
这个类对外提供了name(),operator==()等方法供用户使用.
-
typeid()可以对基本的数据类型和对象进行操作,这种情况下,是在编译期静态决定的
-
type_info也可以对类类型和类对象进行操作
如果是声明了虚函数的类对象引用,则typeid()返回的是实际对象的类型信息,在运行时动态决定的;
反之,则typeid()返回的是入参声明类型信息,在编译时静态决定的.
需要引入#include
基本数据类型和对象
typeid()可以对基本的数据类型和对象进行操作,这种情况下,是在编译期静态决定的
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int a = 3;
int b = 4;
const std::type_info& tp3 = typeid(a);
const std::type_info& tp4 = typeid(b);
cout<<&tp3<<endl;
cout<<&tp4<<endl;
cout<<tp3.name()<<endl;
cout<<tp4.name()<<endl;
if(tp3==tp4){
cout<<"yes!"<<endl;
}
return 0;
}
/*
0x5613881a9d40
0x5613881a9d40
i
i
yes!
*/
虚函数的类对象
虚函数指针房间的地址,找到抽屉柜
抽屉柜格子的上面有一个亚克力盒子,上面有了RT两个字母,这个盒子里放的是RTTI玻璃柜的地址
RTTI玻璃柜的前三层放的是贵重物品,上了锁,看不到,但是第四层是可以打开的
打开以后发现里面放着一个户型图礼盒的地址
走到这个地址去,把户型图打开,就可以看到户型的名字
#include <iostream>
using namespace std;
class Person //人
{
public:
virtual void fun()
{
cout << "全价票" << endl; //成人票全价
}
};
class Student : public Person //学生
{
public:
virtual void fun() //子类完成对父类虚函数的重写
{
cout << "半价票" << endl;//学生票半价
}
};
class Soldier : public Person{
public:
virtual void fun()
{
cout << "军人票" << endl;
}
};
int main()
{
Person* p1 = new Student;
long* p2 = (long*)p1;
long* vp = (long*)(*p2);
typedef void(*Func)(void);
Func f = (Func)vp[0];
f();
long* vr = (long*)(*(vp-1));
long* vr2 = vr + 3;
long* vr3 = (long*)(*vr2);
const type_info* preal = (const type_info*)vr3;
cout<<preal->name()<<endl;
cout<<"-------------"<<endl;
cout<<typeid(*p1).name()<<endl;
}
/*
半价票
7Student
-------------
7Student
*/
long* p2 = (long*)p1; p2是大房子的地址
long* vp = (long* )(*p2); *p2是房子里唯一房间vtpr里住的人
f();证明虚函数表地址没拿错;
long* vr = (long* )(* (vp-1));找到RT亚克力盒子,vp-1是RT亚克力房子的地址;* (vp-1)就是把房子里的东西拿出来,拿出来的东西就是RTTI玻璃柜的地址
long* vr2 = vr + 3;//拿到玻璃柜第四个格子放置的地址vr2
long* vr3 = (long )( vr2);//把第四个格子里的东西拿出来,这个里面的东西就是户型盒的地址
要向得到正确的结果,父类必须要有虚函数。只有当父类含有虚函数时,编译器才会对typeid中的表达式进行求值,否则,typeid返回的是表达式参数定义时的类型(静态类型)
int main()
{
Person* p1 = new Student;
Person* p2 = new Soldier;
cout<<typeid(p1).name()<<endl;
cout<<typeid(p2).name()<<endl;
cout<<typeid(*p1).name()<<endl;
cout<<typeid(*p2).name()<<endl;
}
/*
P6Person
P6Person
7Student
7Soldier
*/
总结
没有虚函数表,RTTI就不复存在