一.宏定义
实现方式有多种,原理是相同的
方式1:
#define get_class_ptr(memberPtr,classType,memberName) \
((classType*)((char*)(memberPtr)-(unsigned long)((ULONG_PTR)&((classType*)0)->member)))
方式2:
#define get_class_ptr(memberPtr,classType,memberName) \
((classType*)(reinterpret_cast<char*>(memberPtr)-(unsigned long)&(reinterpret_cast<classType*>(0)->member)))
实现原理:利用c++类的内存分布,初始化的类的成员变量在内存中的储存地址是基于类对象的地址的偏移值确定的,已知成员变量的内存地址,再减去类结构的各个成员变量基于类基址的偏移值,就可以计算出类对象的内存地址,不同的类结构,内存结构也不同,详情参考文末参考文章,讲解的比较详细
二.测试示例
以下代码属于类似伪代码,只描述大致流程,和特定场景使用
#define get_class_ptr(memberPtr,classType,memberName) \
((classType*)((char*)(memberPtr)-(unsigned long)((ULONG_PTR)&((classType*)0)->member)))
class A
{
public:
A();
~A();
public:
int m_TestOne;
int m_TestTwo;
}
class B
{
public:
B()
{
m_aPtr=new A();
}
~B();
public:
A *m_aPtr;
int m_TestB;
}
int main()
{
//假设已经存在类B,且已初始化,但是由于某种原因不知道bObj的内存地址,
//但是知道类成员aPtr的内存地址
B *bObj=new B();
A *aObjTem=bObj->m_aPtr
//通过类B成员变量m_aPtr获取bObj的地址
B *bObjTemp = get_class_ptr(aObjTem,B,m_aPtr);
reurn 0;
}