当前位置: 首页 > news >正文

c++typeid()的使用

用处:

typeid()函数主要用来获取对应类型或者变量的类型信息,其返回一个std::type_info的对象,这个对象中存放了对应类型的具体信息。

所以typeid()函数就是获取一个type_info的类型,然后可以通过此类型来获取到相应的类型信息。

type_info的声明 

class type_info {
public:virtual ~type_info();bool operator==(const type_info& rhs) const;bool operator!=(const type_info& rhs) const;bool before(const type_info& rhs) const;const char* name() const;private:// 私有构造函数、复制构造函数和赋值运算符,以防止直接创建和复制type_info(const type_info&);type_info& operator=(const type_info&);
};

 这个类中你会发现内部有包含很多关于类型信息的操作函数。
 1. name();  // 可以获取到对应类型信息的名字。

 2. 重载了比较运算符,可以对获取到的类型信息进行比较。

 3. 主要的是,其赋值构造函数和有参构造函数,都设置为了私有的,在别的编译器实现可能会使用=delete删除掉,也就意味着我们没有办法使用type_info类定义对象,所以只有使用typeid才能够获取type_info类型的对象,来获取对应的信息。
 

注意:   type_info类型和typeid的实现是基于编译器的,也就是说c++只是提出了基于语法的层面,对于具体的实现不同的编译器是不一样的,但是用法都是类似的。

typeid的具体使用: 

首先说明,typeid的实现一般是基于虚函数的,当然是我们自己定义的类型,所以建议都使用虚函数。


原因是因为,基于c++的多态,虚函数会保存一个虚函数表的指针,虚函数表中会存储一个type_info的类型信息,但是至于存储在哪个位置,这是由编译器决定的,不同的编译器不一样,我们实际使用的时候没有必要关心。typeid就是借助虚函数表的机制可以判断出多态下父类指针指向的具体实际类型。

具体其实如何得知的,我猜测,应该是当父类的指针指向子类对象实现多态的时候,其对应父类的type_info信息的类型就会修改为其指向的子类类型。(不一定正确)

其实原因就是在多态的实现过程中,可以获取到对应指针指向的实际类型。

 定义一下三个类进行测试:

class People {
public:People() = default;virtual void write() {std::cout << "People\n";}
};class Man : public People {
public:Man() = default;virtual void write() override {std::cout << "Man\n";}
};class Woman : public People {
public:Woman() = default;virtual void write() override {std::cout << "Woman\n";}
};int main(void) {People* p1 = new People;Man* m1 = new Man;People* p2 = m1;    // 使用多态std::cout << typeid(p1).name() << std::endl;  // class People*std::cout << typeid(m1).name() << std::endl;  // class Man*std::cout << typeid(p2).name() << std::endl;  // class People*std::cout << typeid(*p2).name() << std::endl;  // class Manreturn 0;
}

对应的输出结果已经在函数调用之后了,记住typeid函数返回一个type_info类型的对象,但是我们不能使用这样的类型去接收,因为外部不可定义其对象,所以获取type_info类型只有通过typeid,所以获取之后直接使用这个对象。

代码中调用name()获取具体对象的类型。

仔细看最后一个打印信息,p2是一个父类指针对象,所以其类型是父类指针类型,但是*p2则不一样,由于多态的实现,*p2就是p2指针实际指向的类型,此处为Man类型,所以我们使用typeid检测之后得到的就是Man类型的数据。

也可以用于一般类型: 

std::cout << typeid(int) << std::endl;  // int

类型进行比较

if(typeid(int) == typeif(float)){}else{}

 我们可以直接使用==比较两个类型是否相同,相同执行一个分支否则执行另外一个分支,实现运行时类型检查,不同的类型情况进行不用的代码。

dynamic_cast借助typeid进行运行时类型检测 

dynamic_cast是c++新增的类型强制转换,其主要用于继承系列的类型转换,成功返回转换后的指针,失败返回NULL。


其就是根据typeid获取对应的变量的实际类型,然后根据继承树来判断是否可以转换,子类转父类没问题,父类转子类会返回NULL。

http://www.lryc.cn/news/410630.html

相关文章:

  • 【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十四)-租云服务器及配环境、docker基本命令
  • 实现一个全栈模糊搜索匹配的功能
  • 智慧景区导览系统小程序开发
  • HIVE调优方式及原因
  • deploy local llm ragflow
  • 测桃花运(算姻缘)的网站系统源码
  • 电商平台优惠券
  • 内衣洗衣机多维度测评对比,了解觉飞、希亦、鲸立哪款内衣洗衣机更好
  • 数据结构和算法入门
  • 基于OpenCV C++的网络实时视频流传输——Windows下使用TCP/IP编程原理
  • (BS ISO 11898-1:2015)CAN_FD 总线协议详解6- PL(物理层)规定3
  • docker环境下php安装扩展步骤 以mysqli为例
  • 医院综合绩效核算系统,绩效核算系统源码,采用springboot+avue+MySQL技术开发,可适应医院多种绩效核算方式。
  • ROOM数据快速入门
  • 刷新,前面接口的返回值没有到,第二个接口已经请求完了,导致第二个接口返回数据错误
  • pdcj设计
  • 【数据结构】哈希表的模拟实现
  • 面试经典算法150题系列-数组/字符串操作之多数元素
  • 海南云亿商务咨询有限公司领航抖音电商服务
  • C#初级——继承
  • Github 2024-07-29 开源项目日报 Top10
  • nginx反向代理和负载均衡+安装jdk-22.0.2
  • 软考高级科目怎么选?软考高级含金量排序
  • 【机器学习西瓜书学习笔记——模型评估与选择】
  • vue3+cesium创建地图
  • Zookeeper客户端和服务端NIO网络通信源码剖析
  • 从DevOps到DevSecOps是怎样之中转变?
  • ORM与第三方数据库对接的探讨及不同版本数据库的影响
  • Windows远程桌面无法拷贝文件问题
  • 优化数据处理效率,解读 EasyMR 大数据组件升级