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

本文主要是介绍91 C++对象模型探索。RTTI运行时类型识别回顾 与 存储位置介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,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 Teacher25sonTeacher25base * aa = dynamic_cast<Teacher25base *>(ptea);if (aa!=NULL) {cout << "aa == success" << endl; //okaa->func();//注意这里:Teacher25son virtual func called}else {cout << "fail" << endl;}Teacher25son * bb = dynamic_cast<Teacher25son *>(ptea);if (bb != NULL) {cout << "bb = success" << endl;//okbb->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 Teacher25sonTeacher25base * aa = dynamic_cast<Teacher25base *>(ptea);if (aa!=NULL) {cout << "aa == success" << endl; //okaa->func();//注意这里:Teacher25son virtual func called}else {cout << "fail" << endl;}Teacher25son * bb = dynamic_cast<Teacher25son *>(ptea);if (bb != NULL) {cout << "bb = success" << endl;//okbb->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; // intcout << typeid(Teacher25base).name() << endl; //class Teacher25basecout << 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,是基于类的,也是在编译阶段就完成了的,

这篇关于91 C++对象模型探索。RTTI运行时类型识别回顾 与 存储位置介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/666767

相关文章

Spring Boot项目打包和运行的操作方法

《SpringBoot项目打包和运行的操作方法》SpringBoot应用内嵌了Web服务器,所以基于SpringBoot开发的web应用也可以独立运行,无须部署到其他Web服务器中,下面以打包dem... 目录一、打包为JAR包并运行1.打包为可执行的 JAR 包2.运行 JAR 包二、打包为WAR包并运行

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

Java中 instanceof 的用法详细介绍

《Java中instanceof的用法详细介绍》在Java中,instanceof是一个二元运算符(类型比较操作符),用于检查一个对象是否是某个特定类、接口的实例,或者是否是其子类的实例,这篇文章... 目录引言基本语法基本作用1. 检查对象是否是指定类的实例2. 检查对象是否是子类的实例3. 检查对象是否

C++类和对象之初始化列表的使用方式

《C++类和对象之初始化列表的使用方式》:本文主要介绍C++类和对象之初始化列表的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C++初始化列表详解:性能优化与正确实践什么是初始化列表?初始化列表的三大核心作用1. 性能优化:避免不必要的赋值操作2. 强

C++迭代器失效的避坑指南

《C++迭代器失效的避坑指南》在C++中,迭代器(iterator)是一种类似指针的对象,用于遍历STL容器(如vector、list、map等),迭代器失效是指在对容器进行某些操作后... 目录1. 什么是迭代器失效?2. 哪些操作会导致迭代器失效?2.1 vector 的插入操作(push_back,

什么是ReFS 文件系统? ntfs和refs的优缺点区别介绍

《什么是ReFS文件系统?ntfs和refs的优缺点区别介绍》最近有用户在Win11Insider的安装界面中发现,可以使用ReFS来格式化硬盘,这是不是意味着,ReFS有望在未来成为W... 数十年以来,Windows 系统一直将 NTFS 作为「内置硬盘」的默认文件系统。不过近些年来,微软还在研发一款名

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL