美文网首页
C++<第三十一篇>:typeid运算符

C++<第三十一篇>:typeid运算符

作者: NoBugException | 来源:发表于2022-01-29 12:21 被阅读0次

typeid 运算符是用来获取一个表达式的类型信息。
类型信息对于编程语言非常重要,它描述了数据的各种属性。
对于基本类型(int、float 等等)的数据类型信息所包含的内容比较简单,主要是指数据的类型。
对于类类型的数据(也就是对象),类型信息是指对象所属的类、所包含的成员、所在的继承关系等。
类型信息是创建数据的模板,数据占用多大内存,能进行什么样的操作、该如何操作等,这些都由它的类型信息决定。

(1)typeid 的定义

const type_info& type_info变量 = typeid(类型或表达式);

typeid 是一个标准库 typeinfo 中的函数,所以需要添加如下代码:

#include <typeinfo>

就拿获取普通数据类型来举例:

    int a = 10;
    const type_info& mInfo = typeid(a);
    cout << mInfo.name() << endl; // 获取类型的名称
    cout << mInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo.hash_code() << endl; // 获取类型对象的hash code

输出结果是:

int
.H
12638232278978672507

typeid 的使用非常灵活,它的操作数可以是普通变量、对象、内置类型(int、float等)、自定义类型(结构体和类),还可以是一个表达式。

type_info 类的几个成员函数,下面是对它们的介绍:

  • name() 用来返回类型的名称。
  • raw_name() 用来返回名字编码(Name Mangling)算法产生的新名称。
  • hash_code() 用来返回当前类型对应的 hash 值。hash 值是一个可以用来标志当前类型的整数,有点类似学生的学号、公民的身份证号、银行卡号等。不过 hash 值有赖于编译器的实现,在不同的编译器下可能会有不同的整数,但它们都能唯一地标识某个类型。

(2)type_info 成员函数介绍

size_t hash_code() const;
返回一个类的hash code,它是类的唯一标志。

const char* name() const;
返回一个能表示类型名称的字符串。
但是C++标准并没有规定这个字符串是什么形式的,例如对于上面的objInfo.name()语句,VC/VS 下返回“class Base”,但 GCC 下返回“4Base”。

const char* raw_name() const;
返回名字编码(Name Mangling)算法产生的新名称。

bool before (const type_info& rhs) const;
判断一个类型是否位于另一个类型的前面,rhs 参数是一个 type_info 对象的引用。
但是C++标准并没有规定类型的排列顺序,不同的编译器有不同的排列规则,程序员也可以自定义。要特别注意的是,这个排列顺序和继承顺序没有关系,基类并不一定位于派生类的前面。

bool operator== (const type_info& rhs) const;
重载运算符“==”,判断两个类型是否相同,rhs 参数是一个 type_info 对象的引用。

bool operator!= (const type_info& rhs) const;
重载运算符“!=”,判断两个类型是否不同,rhs 参数是一个 type_info 对象的引用。

(3)typeid支持哪些数据类型

typeid 支持 基本数据类型类类型

演示代码如下:

    int a = 10;
    const type_info& mInfo1 = typeid(a); // 整型变量
    cout << mInfo1.name() << endl; // 获取类型的名称
    cout << mInfo1.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo1.hash_code() << endl; // 获取类型对象的hash code

    const type_info& mInfo2 = typeid(int); // 整数类型
    cout << mInfo2.name() << endl; // 获取类型的名称
    cout << mInfo2.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo2.hash_code() << endl; // 获取类型对象的hash code

    float b = 10.1f;
    const type_info& mInfo3 = typeid(b); // 浮点型变量
    cout << mInfo3.name() << endl; // 获取类型的名称
    cout << mInfo3.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo3.hash_code() << endl; // 获取类型对象的hash code

    D d;
    const type_info& mInfo4 = typeid(d); // 普通类对象
    cout << mInfo4.name() << endl; // 获取类型的名称
    cout << mInfo4.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo4.hash_code() << endl; // 获取类型对象的hash code

    const type_info& mInfo5 = typeid(D); // 类类型
    cout << mInfo5.name() << endl; // 获取类型的名称
    cout << mInfo5.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo5.hash_code() << endl; // 获取类型对象的hash code

    const type_info& mInfo6 = typeid(struct STU); // 结构体类型
    cout << mInfo6.name() << endl; // 获取类型的名称
    cout << mInfo6.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo6.hash_code() << endl; // 获取类型对象的hash code

    const type_info& mInfo7 = typeid(1 + 2 + 3 + 4); // 表达式
    cout << mInfo7.name() << endl; // 获取类型的名称
    cout << mInfo7.raw_name() << endl; // 获取名字算法产生的新名称
    cout << mInfo7.hash_code() << endl; // 获取类型对象的hash code

(4)判断类型是否是同一类型

决定两者是否相等取决于:不仅hash code要一样,而且值也需要一样。

typeid 运算符只能判断两者之间的类型是否一致,它不能判断两者是否相等。

【基本数据类型举例】

    int a = 10;
    const type_info& aInfo = typeid(a); // 整型变量
    cout << aInfo.name() << endl; // 获取类型的名称
    cout << aInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << aInfo.hash_code() << endl; // 获取类型对象的hash code

    int b = 11;
    const type_info& bInfo = typeid(b); // 整型变量
    cout << bInfo.name() << endl; // 获取类型的名称
    cout << bInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << bInfo.hash_code() << endl; // 获取类型对象的hash code

    const type_info& intInfo = typeid(int); // 整数类型
    cout << intInfo.name() << endl; // 获取类型的名称
    cout << intInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << intInfo.hash_code() << endl; // 获取类型对象的hash code

    bool isEqual1 = aInfo.operator==(bInfo);
    cout << isEqual1 << endl;
    
    bool isEqual2 = aInfo.operator==(intInfo);
    cout << isEqual2 << endl;

    bool isEqual3 = intInfo.operator==(bInfo);
    cout << isEqual3 << endl;

代码是基本数据类型a和b,以及int比较,输出结果是:

int
.H
12638232278978672507
int
.H
12638232278978672507
int
.H
12638232278978672507
1
1
1

我们发现,aInfo、bInfo、intInfo 三者的hash code一致,并且 operator== 函数的返回值为1,1表示相等。

如果是int数据和float数据比较呢?

    int a = 10;
    const type_info& aInfo = typeid(a); // 整型变量
    cout << aInfo.name() << endl; // 获取类型的名称
    cout << aInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << aInfo.hash_code() << endl; // 获取类型对象的hash code

    float b = 11.1f;
    const type_info& bInfo = typeid(b); // 浮点变量
    cout << bInfo.name() << endl; // 获取类型的名称
    cout << bInfo.raw_name() << endl; // 获取名字算法产生的新名称
    cout << bInfo.hash_code() << endl; // 获取类型对象的hash code

    bool isEqual1 = aInfo.operator==(bInfo);
    cout << isEqual1 << endl;

输出结果是:

int
.H
12638232278978672507
float
.M
12638226781420530164
0

两者hash code不同,并且 operator== 函数的返回值为0,0表示不相等。

【类类型举例】

    D d1;
    const type_info& aInfo = typeid(d1);
    cout << aInfo.name() << endl;
    cout << aInfo.raw_name() << endl;
    cout << aInfo.hash_code() << endl;

    const type_info& bInfo = typeid(D);
    cout << bInfo.name() << endl;
    cout << bInfo.raw_name() << endl;
    cout << bInfo.hash_code() << endl;

    bool isEqual = aInfo.operator==(bInfo);
    cout << isEqual << endl;

输出结果是:

class D
.?AVD@@
5621110339268995829
class D
.?AVD@@
5621110339268995829

1

operator== 函数的返回值为1,1表示相等。

    D* d1 = new D();
    D* d2 = new D();
    const type_info& aInfo = typeid(*d1);
    cout << aInfo.name() << endl;
    cout << aInfo.raw_name() << endl;
    cout << aInfo.hash_code() << endl;

    const type_info& bInfo = typeid(*d2);
    cout << bInfo.name() << endl;
    cout << bInfo.raw_name() << endl;
    cout << bInfo.hash_code() << endl;

    bool isEqual = aInfo.operator==(bInfo);
    cout << isEqual << endl;

输出结果是:

class D
.?AVD@@
5621110339268995829
class D
.?AVD@@
5621110339268995829

1

operator== 函数的返回值也为1,1表示相等。

通过以上举例,已经可以充分证明:typeid 运算符只能判断两者之间的类型是否一致,它不能判断两者是否相等。

(5)判断是否是某个类型

程序设计中,typeid运算符常常用来判断都对象是否是某个类型。

演示代码如下:

#include <iostream>
#include <typeinfo>

using namespace std;

class D 
{
public:
    void display()
    {
        cout << "我的类型是D" << endl;
    }
};

template <class T>
class MyTemplate
{
    T t;

public:
    MyTemplate(T tt)
    {
        t = tt;
    }
    void display()
    {
        const type_info& typeInfo = typeid(D);
        if (typeInfo.operator==(typeid(t))) 
        {
            D d;
            d.display();
        }
        else
        {
            cout << "我的类型不是D" << endl;
        }
    }
};

int main() {

    D d;
    MyTemplate<D> temp(d);
    temp.display();
   
    return 0;
}

使用模板时,并不知道模板类型到底是什么类型,可能针对不同类型的数据输出不同的结果,这个时候就需要使用 typeid 函数了。

[本章完...]

相关文章

  • typeid

    本文分析C++中typeid的实现原理 1. 前言 1.1 typeid C++里面的typeid是个运算符,返回...

  • C++<第三十一篇>:typeid运算符

    typeid 运算符是用来获取一个表达式的类型信息。类型信息对于编程语言非常重要,它描述了数据的各种属性。对于基本...

  • C++如何优雅的打印出变量类型

    方法1:使用C++库自带的typeid函数 一般使用C++库中的typeid函数获取一个变量的类型,不过打印出来的...

  • c++关键字typeid

    typeid是c++的一个关键字,typeid操作符的返回结果是标准库类型type_info对象的引用。 但是,C...

  • 1.2.15_C++ 关系运算符重载

    C++ 重载运算符和重载函数 C++ 语言支持各种关系运算符( < 、 > 、 <= 、 >= 、 == 等等),...

  • 1.2.17_C++ ++ 和 -- 运算符重载

    C++ 重载运算符和重载函数 递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符...

  • 第十一章 使用类

    运算符重载 运算符重载是一种形式的C++多态。运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。...

  • C++ 运算符重载

    运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。实际上,很多C++运算符已经重载。将*运算符用...

  • 第三章 数据处理(4)c++算数运算符

    (四)c++算数运算符 1.算数运算符 c++一共有五种基本的算数运算符,+, -, *, /, %分别是加减乘...

  • C++ 重载运算符

    C++重载运算符

网友评论

      本文标题:C++<第三十一篇>:typeid运算符

      本文链接:https://www.haomeiwen.com/subject/vestkrtx.html