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()处理对象是有关的,所以在实际的工程中是不能这么使用,仅限于研究对象的模型。

posted @ 2016-03-26 18:27  wkrs  阅读(326)  评论(0)    收藏  举报