我们知道指针是地址,而地址实际上是个整数。
看三个类A、B、C(A,B都是抽象类,即都有纯虚函数)之间的继承关系:
class A
{
long member1;
virtual func1()=0;
}
class B
{
long member2;
virtual func2()=0;
}
class C:public A,public B
{
long member3;
func1() {...};
func2() {...};
}memory layout of instance of A:
--vtbl of A
--member1
memory layout of instance of B:
--vtbl of B
--member2
注意:
memory layout of instance of C:
--vtbl of C(also is of A)
--member1
--vtbl of B
--member2
--member3
看到了吗?B在C的实例中的偏移是:(pointer to B(vtbl of B))-(pointer to C(vtbl of C))
具体地说,假设C的指针为8,即C的实例在地址8处,则C中的A在8处,member1在12处,C中的B在16处,member2在20处,member3在24处。因此B在C中的偏移为8。这是以Project Settings中的Struct member align=1为标准算出的,如果struct member align=8,则:
A=8,member1=16,B=24,member2=32,member3=40, B偏移为16.
static_cast<base*>((derived*)_ATL_PACKING))得到的是某派生类实例中的基类的指针,_ATL_PACKING为派生类实例的指针,这样offsetofclass得到的便是派生类的一个基类在派生类的实例中的偏移量。