美文网首页
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 函数了。

    [本章完...]

    相关文章

      网友评论

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

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