91 C++对象模型探索。数据语义学 - RTTI运行时类型识别回顾 与 存储位置介绍

本文详细介绍了C++中的RTTI(运行时类型信息)机制,包括其原理、使用方法(如typeid和dynamic_cast),以及RTTI与虚函数、多态的关系。重点讨论了vptr和vtbl的作用,以及type_info的存储位置。
摘要由CSDN通过智能技术生成

一,RTTI 运行时类型识别,简单回顾

C++运行时类型识别RTTI,要求父类这种必须 至少有一个虚函数,如果父类中没有虚函数,那么得到的RTTI就不准确;

RTTI就可以在执行期间查询一个多态指针,或者多态应用的信息了

RTTI的能力 靠 typeid和dynamic_cast运算符来体现。

class Teacher25base {
public:
	void virtual func() {
		cout << "Teacher25base virtual func called" << endl;
	}
	virtual ~Teacher25base(){
		cout << "Teacher25base virtual 析构函数被调用" << endl;
	}
};

class Teacher25son :public Teacher25base{

public:
	void virtual func() {
		cout << "Teacher25son virtual func called" << endl;
	}

	virtual ~Teacher25son() {
		cout << "Teacher25son virtual 析构函数被调用" << endl;
	}
};

void main() {
	Teacher25base *ptea = new Teacher25son;
	ptea->func();
	cout << "------" << endl;
	cout << typeid(ptea).name() << endl;//class Teacher25base *
	cout<<typeid(*ptea).name() << endl; //class Teacher25son

	Teacher25base * aa = dynamic_cast<Teacher25base *>(ptea);
	if (aa!=NULL) {
		cout << "aa == success" << endl; //ok
		aa->func();//注意这里:Teacher25son virtual func called
	}
	else {
		cout << "fail" << endl;
	}

	Teacher25son * bb = dynamic_cast<Teacher25son *>(ptea);
	if (bb != NULL) {
		cout << "bb = success" << endl;//ok
		bb->func(); //注意这里:Teacher25son virtual func called
	}
	else {
		cout << "fail" << endl;
	}
}

二 RTTI运行原理以及常用方法,以及RTTI的保存位置

typeid 返回的是一个常量对象的引用。

这个常量对象的类型一般是type_info(类)

class Teacher25base {
public:
	void virtual func() {
		cout << "Teacher25base virtual func called" << endl;
	}
	virtual ~Teacher25base(){
		cout << "Teacher25base virtual 析构函数被调用" << endl;
	}
};

class Teacher25son :public Teacher25base{

public:
	void virtual func() {
		cout << "Teacher25son virtual func called" << endl;
	}

	virtual ~Teacher25son() {
		cout << "Teacher25son virtual 析构函数被调用" << endl;
	}
};

void main() {
	Teacher25base *ptea = new Teacher25son;
	ptea->func();
	cout << "------" << endl;
	cout << typeid(ptea).name() << endl;//class Teacher25base *
	cout<<typeid(*ptea).name() << endl; //class Teacher25son

	Teacher25base * aa = dynamic_cast<Teacher25base *>(ptea);
	if (aa!=NULL) {
		cout << "aa == success" << endl; //ok
		aa->func();//注意这里:Teacher25son virtual func called
	}
	else {
		cout << "fail" << endl;
	}

	Teacher25son * bb = dynamic_cast<Teacher25son *>(ptea);
	if (bb != NULL) {
		cout << "bb = success" << endl;//ok
		bb->func(); //注意这里:Teacher25son virtual func called
	}
	else {
		cout << "fail" << endl;
	}

	const std::type_info &tp = typeid(*ptea);

	if (typeid(Teacher25son).name() == typeid(*ptea).name() )
	{
		cout << "相等" << endl;
	}
	else {
		cout << "bu相等" << endl;
	}
	//静态用法,不属于多态类型
	cout << typeid(int).name() << endl; // int
	cout << typeid(Teacher25base).name() << endl; //class Teacher25base
	cout << typeid(Teacher25base).raw_name() << endl;//.?AVTeacher25base@@
	cout << typeid(Teacher25base *).name() << endl;//class Teacher25base *
	cout << typeid(Teacher25base *).raw_name() << endl;//.PAVTeacher25base@@
	Teacher25base *ptea5 = new Teacher25base();
	cout << typeid(ptea5).name() << endl;//class Teacher25base *
	cout << typeid(*ptea5).raw_name() << endl;//.?AVTeacher25base@@

	cout << "断点在这里" << endl;

	//当我们把基类中的虚函数 都删除后,
	//测试如下的代码
	Teacher25base *ptea6 = new Teacher25son;
	cout << typeid(ptea6).name() << endl;//在基类没有虚函数的情况下,这块显示为 class Teacher25base
	//这说明:RTTI 一定和虚函数表有关系。如果没有虚函数表,RTTI就不准确。

	//没有虚函数的调用,没有父类子类的继承,就没有多态。

}

三 那么这个RTTI的保存位置在哪里呢?


 

四。vptr,vtbl,rtti的type_info信息 构造时机

vptr 虚函数指针,是基于类对象的,是在构造函数的时候,由编译器赋值的。

vtbl 虚函数表,是基于类的,是在编译阶段就完成了的,在代码段保存

rtti 的type_info,是基于类的,也是在编译阶段就完成了的,在代码段保存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值