zoukankan      html  css  js  c++  java
  • C++ 的 typeinfo 内存问题

    Attention:本文旨在分析获取对象类型时程序内部是如何处理的,不能用于工程代码中,因为不同的编译器的实现是不同的,C++标准并未规定具体的实现方式。实验环境:Ubuntu 14.04 i686 GCC 4.8.4

       我们可以使用typeid来获取对象的具体名称,示例代码如下:

    class Base
    {
    public:
        virtual void doSome() { }
        virtual ~Base() { }
    };
    
    class TypeTest: public Base { };
    
    int main()
    {
        Base* p = new TypeTest;
        cout<<typeid(TypeTest).name() <<endl;
        cout<<typeid(p).name() <<endl;
        cout<<typeid(*p).name() <<endl;
        delete p;
        return 0;
    }

    输出的结果如下:

    在这段代码中前两个输出类型和第三个是不同的,因为前两个的类型编译器可以在编译期就确定了,而第三个的输出结果编译器在编译期是无法知道的,只有在执行的时候才能确定。也就是说这和C++的多态效果是一样的。

    既然这也是一种多态行为,那么它的对象信息也应该能通过virtual table来获取,这样才能在运行期获取指针所指的具体类型。通过查阅资料我们可以猜测TypeTest的内存布局应该如下图所示,那么我们可以通过指针来进行验证是否如此。

    验证代码:

    cout<<typeid(*p).name() <<endl;
    printf("%s\n", (char*)(*(int*)p);
    // 之所以使用printf是为了防止cout进行某些重载操作
    // 输出:
    //      8TypeTest
    //      8TypeTest

    从输出结果来看和我们猜测的完全一致。但是在有一次我在代码的后面加了一行代码就出现问题了。

    cout<<typeid(*p).name() <<endl;
    printf("%s\n", (char*)(*(int*)p);
    cout<<typeid(string).name() <<endl;

    输出结果:

    让我很费解的是我在下面输出别的内容居然会影响到对象的数据,当然这和typeid()处理对象是有关的,所以在实际的工程中是不能这么使用,仅限于研究对象的模型。

  • 相关阅读:
    Java 类与类之间的调用
    File类中的list()和listFiles()方法
    关于GITLAB若干权限问题
    JAVA 判断一个字符串是不是一个合法的日期格式
    JAVA日期加减运算
    Java读写文件的几种方法
    在Coding.net创建项目开发
    IntelliJ IDEA 创建项目project和module的关系
    对xml文件的简单解析
    Intellij IDEA使用总结
  • 原文地址:https://www.cnblogs.com/benjaming/p/5251465.html
Copyright © 2011-2022 走看看