Howto:从C++对象指针得到类名

本文详细介绍了C++运行时类型信息(RTTI)的两种实现方式:语言本身的RTTI及MFC的CObject。通过具体实例说明如何在含有虚函数的类中获取类型信息,并展示了如何使用这些信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


JAVA程序在运行的时候,有丰富的动态类型信息。而C++则困难的多。C++的运行时类型信息有3种实现方式:语言本身的RTTI、MFC的CObject、QT的moc。下面仅介绍前两种。
一、语言本身的RTTI:
如果是POD类型,如:
class PodPoint{
public:
    int x;
    int y;
};
那么它和C语言中的struct没有什么区别。sizeof(PodPoint)=8。
偏移值 内容
0 x
4 y
 
别妄想能从它的对象指针中得到什么类型信息。
 
如果它有虚函数,那么就不一样了
class PodPoint{
public:
    int x;
    int y;
    virtual ~PodPoint(){};
};
在32位程序中,sizeof(PodPoint)=12。这是因为凡是有虚函数,就必须有vtable。所以PodPoint的实际布局就变成了这样:
偏移值 内容
0 指向vtable的指针
4 x
8 y
如果编译的时候打开了RTTI(在vc2005及以上版本默认会打开),那么就很有意思了。在vtable[-1]的位置,是一个特殊的指针,指向RTTI Complete Object Locator,它的第12个字节开始,是一个指针,指向type_info对象。于是我就写了下面这样的代码:
void printMyClassInfo(void *p){
    type_info*** vtable=(type_info***)(*(int*)p);
    type_info** v1=vtable[-1];
    type_info* v=v1[3];
    printf("%s\n",v->name());
}
在有vtable的情况下,这个函数工作的非常好。
二、MFC的RTTI
MFC中的大多数对象都从CObject继承而来,例如:
class MyPoint:public CObject{
public:
    int x;
    int y;
    DECLARE_DYNAMIC(MyPoint)
};
IMPLEMENT_DYNAMIC(MyPoint,CObject)
 
那么我们就可以通过调用CObject的
virtual CRuntimeClass* GetRuntimeClass() const
来得到类名。这个函数一般就在vtable的第一个。
代码如下:
void printClassInfo(void *p){
    int vtable=*(int*)p;
    CRuntimeClass* info;
    __asm{
        mov ecx,p;
        mov eax,vtable;
        call [eax];
        mov info,eax;
    }
    printf("%s",info->m_lpszClassName);
};
假如将上面的IMPLEMENT_DYNAMIC和DECLARE_DYNAMIC去掉,那么输出的结果将是”CObject”,而不是”MyPoint”,原因很简单。因为子类没有覆盖基类的这个方法嘛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值