zoukankan      html  css  js  c++  java
  • typeid 使用说明

    //z 2011-05-10 20:04:52@is2120

    http://blog.csdn.net/is2120/archive/2011/05/10/6410096.aspx

    tag: c++ typeid 实现 使用 用法

     

    typeid是什么?
    是c++的一个操作符,用于获取一个表达式的类型

     

    typeid如何实现
    typeid (5.3.7): find vtable, through that find most derived class object, then extract type_info from that object's vtable. It is still very slow comparing with function call;

     

    typeid使用的几种情况:

     

    1. 操作类型是内置类型或是常量
    int i;
    cout << typeid(i).name() << endl;//z 输出:int
    cout << typeid(0.0f).name() << endl; //z 输出:double

     
    //z 2011-05-10 20:04:52@is2120

    2. 操作类型为类类型
    分两种情况
    2.1 类不带虚函数
    typeid会指出操作数的类型,而不是底层对象的类型。
    class B{};
    class D:public B {};

     

    D d;
    B* pb = &d;//z 此时pb实际指向的底层类型为DERIVED

     

    cout << typeid(*pd).name() <<endl;//z 输出B


     (在vc下,使用typeid的时候,如果typeid施加给的类型是没有vptr的class或者根本不是class
    那么汇编是
    mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
    也就是编译器生成一个简单的type_info对象的表,并且在编译期静态决定下标,做一个简单查表操作。 )

    2.2 带虚函数
    class B{public: virtual void foo(){}};
    class D:public B{};

     

    D d;
    B* pb = &d;
    cout << typeid(*pb).name() << endl;//z 输出D

     

    3. 操作类型为一个指针时
    就如同1一样了,会输出操作数的类型,而不是其底层指向的类型。

     

    一个例子:
    //z 2011-05-10 20:04:52@is2120

     

    #include <iostream>
    #include <typeinfo>

     

    using namespace std;

     

    class B
    {
    public:
        virtual void foo(){};
    };

     

    class D : public B
    {
    public:
        virtual void foo(){};
    };

     

    int main()
    {
        D d;
        B& b = d;
        B* pb = &d;
        D* pd = dynamic_cast<D*>(&b);

     

        cout << typeid(b).name() << endl;
        cout << typeid(d).name() << endl;
        //z 这里输出 B*是因为pb是一个指针,而不是一个类类型。
        //z 为了获取到派生类的类型,typeid的操作对象必须是一个类类型
        cout << typeid(pb).name() << endl;
        cout << typeid(*pb).name() << endl;
        cout << typeid(pd).name() << endl;
        cout << typeid(*pd).name() << endl;
    }

     

    /* 输出如下:
    class D
    class D
    class B *
    class D
    class D *
    class D
    */

     

    4. 是否会对效率造成影响(cost,overhead)
    为实现typeid,需要在vtable中添加一个指针,指向type information structure。
    同普通的成员函数(function call)比起来,会慢一些
    但是具有虚函数的类总是创建和初始化vtable,这里只是增加了一个指针,所以不会带来什么性能上的开销。

     

    5. 环境
    vc下,通过/GR 启用RTTI
    gcc默认是启用的,可以通过 -fno-rtti 选项禁用

    //z 2011-05-10 20:04:52@is2120

    http://blog.csdn.net/is2120/archive/2011/05/10/6410096.aspx

  • 相关阅读:
    [Swift]LeetCode32. 最长有效括号 | Longest Valid Parentheses
    [Swift]LeetCode31. 下一个排列 | Next Permutation
    [Swift]LeetCode30. 与所有单词相关联的字串 | Substring with Concatenation of All Words
    [Swift]LeetCode29. 两数相除 | Divide Two Integers
    时光轴的设计理念
    ITFriend开发日志20140611
    ITFriend开发日志20140611
    高中生活--第7篇–我为什么不交作业
    高中生活--第7篇–我为什么不交作业
    ITFriend网站内测公测感悟
  • 原文地址:https://www.cnblogs.com/IS2120/p/6746048.html
Copyright © 2011-2022 走看看