提出问题
给定一个类:
struct A
{
int a0;
int a1;
int a3;
};
如何取得各成员相对于类地址的偏移量?
解决问题
一种方法如下:
#define MEMOFFSET1(Class, Member) (reinterpret_cast<char*>(&static_cast<Class*>(0)->Member) - reinterpret_cast<char*>(0))
首先强制类型转换成为char*指针,保证计数是以字节为单位,然后指针做减法,得到整形,由于是用空指针做类型转换,因此后面的减数指针的值为0
#define MEMOFFSET2(Class, Member) (reinterpret_cast<int>(&static_cast<Class*>(0)->Member))
当然这种表达方式让我很费解,为什么不能时使用static_cast将指针转换成为int型,反而要用reinterpret_cast来转换
其实一开始我想到的是另一种方法,使用指向类成员的指针,例如:
(int)&AAA::a1
cout << &A::a0 << endl;
#include <iostream>
using namespace std;
struct A
{
int a0;
int a1;
int a2;
};
#define MEMOFFSET1(Class, Member) (reinterpret_cast<char*>(&static_cast<Class*>(0)->Member) - reinterpret_cast<char*>(0))
#define MEMOFFSET2(Class, Member) (reinterpret_cast<int>(&static_cast<Class*>(0)->Member))
template<class T>
int RetAddr(T addr)
{
struct
{
union
{
int uiAddr;
T realAddr;
}Addr;
}hackClassPoint;
hackClassPoint.Addr.realAddr = addr;
return hackClassPoint.Addr.uiAddr;
}
int main()
{
cout << MEMOFFSET1(A, a1) << endl;//4
cout << MEMOFFSET2(A, a2) << endl;//8
cout << &A::a0 << endl;//1
cout << &A::a1 << endl;//1
cout << RetAddr(&A::a0) << endl;//0
cout << RetAddr(&A::a2) << endl;//8
//附上强制类型转换的奇怪之处
float fa = 1.0f;
int ia = 1;
int *pia = &ia;
reinterpret_cast<int>(fa); //error C2440: 'reinterpret_cast' : cannot convert from 'float' to 'int'
//Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast
reinterpret_cast<int>(pia);
static_cast<int>(fa);
static_cast<int>(pia);// 'static_cast' : cannot convert from 'int *' to 'int' There is no context in which this conversion is possible
}