【深度C++】之“typeid与type_info”

0. typeid与type_info

typeid是实现 运行时类型识别(run-time type identification, RTTI)功能的方法之一,另一个是dynamic_cast

typeid的返回结果是type_info类型,type_info类型定义在头文件typeinfo中。

1. typeid

typeid使用起来,和decltype差不多。不过decltype返回的是静态类型,typeid可以返回动态类型。

1.1 使用方法

typeid(expr)

expr可以是任意表达式或类型名。

注意:

  1. 当expr不是类类型或不包含虚函数时,返回e的静态类型
  2. 当expr是包含了虚函数的类的左值时,在程序运行时才会得到结果,即动态类型
  3. typeid会忽略顶层const
  4. typeid + 引用,返回引用源类型
  5. typeid + 数组,返回数组类型
  6. typeid + 函数名,返回函数类型

1.2 示例

Derived *derived_ptr = new Derived();
Base *base_ptr = derived_ptr;
// 二者指向同一个对象

if (typeid(*base_ptr) == typeid(*derived_ptr)) {
    cout << "二者动态类型相同" << endl;
}

if (typeid(*base_ptr) == typeid(Derived)) {
    cout << "base_ptr指向对象的动态类型与Derived相同" << endl;
}

注意:

  1. 指针前面添加了解引用运算符*,否则将得到指针的类型。

1.3 typeid可能会求值

decltype是不会对表达式进行求值的,且结果都是编译时已知的。

但是typeid不同,当类型含有虚函数时,typeid会去求表达式expr的值。

这是很重要的区别

1.4 空指针

typeid + 空指针会抛出bad_typeid异常。

2. type_info类

typeid求值的结果,就是type_info类。

type_info类定义在头文件typeinfo中,它的特点是:

  1. 没有默认构造函数
  2. 拷贝系、移动系及赋值运算符都为delete
  3. 有一个虚析构函数
  4. 可以继承

2.1 唯一创建途径

唯一创建type_info类的途径就是使用typeid运算符。

2.2 类的功能

type_info类的精确定义,随着编译器不同略有差异。

C++标准规定必须提供4个操作:

  1. 可以判断==
  2. 可以判断!=
  3. 返回C风格字符串的函数name()
  4. 返回bool的before()
bool a = true;
short b = 10;
int c = 10;
long d = 10;
long long e = 10;
char f = 'c';
float g = 1.0;
double h = 1.0;
long double i = 1.0;

int arr[5] = {1, 2, 3, 4, 5};
int *ic = &c;
int &rc = c;

Derived der;
Base &base_ref = der;

cout << "       bool 类型type_info的name: " << typeid(a).name() << '\n'
     << "      short 类型type_info的name: " << typeid(b).name() << '\n'
     << "        int 类型type_info的name: " << typeid(c).name() << '\n'
     << "       long 类型type_info的name: " << typeid(d).name() << '\n'
     << "  long long 类型type_info的name: " << typeid(e).name() << '\n'
     << "       char 类型type_info的name: " << typeid(f).name() << '\n'
     << "      float 类型type_info的name: " << typeid(g).name() << '\n'
     << "     double 类型type_info的name: " << typeid(h).name() << '\n'
     << "long double 类型type_info的name: " << typeid(i).name() << '\n'

     << "    int数组 类型type_info的name: " << typeid(arr).name() << '\n'
     << "    int指针 类型type_info的name: " << typeid(ic).name() << '\n'
     << "    int引用 类型type_info的name: " << typeid(rc).name() << '\n'
     << "       子类 类型type_info的name: " << typeid(der).name() << '\n'
     << "     运行时 类型type_info的name: " << typeid(base_ref).name() << endl;

输出:

在这里插入图片描述

环境:

  1. 操作系统:MacOS 10.15.5, 64bit
  2. 编译器:Apple clang version 11.0.3 (clang-1103.0.32.29)
  3. IDE:CLion 2020, built on April 9, 2020
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值