成员(member_name)在类(typen_ame)中的偏移:- (int)(&((type_name*)NULL)->member_name)
例如有个类 A
- class A
-
{
-
public:
-
virtual int show() {}
-
int i1, i2;
-
};
则 (int)(&((A*)NULL)->i2) == 8
类地址+8的偏移处为i2的地址(4字节vmt表地址,4字节i1,所以i2的寻址偏移为8)
这样就能在属性类中自己计算出拥有属性类的类的地址了,这是因为类的寻址方式决定的,如下所示:
- class Child
-
{
-
public:
-
int i1, i2; i1偏移为0, i2为4,无vmt表
-
};
-
-
class Parent
-
{
-
public:
-
int i; i偏移为0
-
Child *c; c偏移为4
-
Parnet() {...} c的new 和 delete就不写了
-
};
-
Parent *p;
这时要new一个Parent类时,会在堆上分配二块内存,一块为c对象占用内存,一块为p对象占用内存.
要寻址类P对象中c对象的i2成员(p->c->i2),大概的汇编代码如下:
- mov ecx, p //得到p的指针
-
mov ecx, [ecx + 4] //得到p对象成员c的指针
-
mov eax, [ecx + 4] //得到c对象成员i2的地址
这样就寻址到了i2
但如果Parent类不是包含的Child类的指针,而是直接包含的对象,情况就不一样了,如下:
- class Parent
-
{
-
public:
-
int i; i偏移为0
-
Child c; c偏移为4(注意不同,这里c不是Child*了)
-
};
-
Parent *p;
这时要new一个Parent类时,只会在堆上分配一块内存,为p对象占用内存,c对象包含在p对象内,直接使用p对象的内存,要寻址类P对象中c对象的i2成员(p->c.i2),大概的汇编代码如下:
- mov ecx, p //得到p的指针
-
mov ecx, ecx + 8 //得到i2的地址 8 = c偏移+i2在c类中的偏移,编译优化
要寻址类P对象中c对象的地址,如下:
- mov ecx, p //得到p的指针
-
mov ecx, ecx + 4 //得到c的地址 p对象指针+偏移
从上面可以看出,只要知道c类地址,要得到p的指针,就 c地址 - c对象在p对象中的偏移就行了.
事情就简单了,示例代码如下:
- #include <iostream>
-
-
using std::cout;
-
using std::cin;
-
using std::endl;
-
-
template<typename T, typename int(*GetOffset)()>
-
class Property
-
{
-
public:
-
Property()
-
{
-
cout << "this:" << (int)this << std::endl;
-
cout << "owner:" << (int)this - GetOffset() << std::endl;
-
}
-
};
-
-
#define PROPERTY_DECLARE(pro_name, type_name)/
-
private: int inline static pro_name##_offset() {return (int)(&((type_name*)NULL)->pro_name);};/
-
public: Property<type_name, type_name::pro_name##_offset> pro_name;
-
-
class PropertyTest
-
{
-
public:
-
int i;
-
public:
-
PROPERTY_DECLARE(Name, PropertyTest)
-
};
-
-
int main()
-
{
-
PropertyTest *test = new PropertyTest();
-
cout << std::endl;
-
cout << "property address:" << (int)(&test->Name) << std::endl;
-
cout << "test class address:" << (int)test << std::endl;
-
-
std::cin.get();
-
return 0;
-
}
----------------------
这是摘抄的文章,挺有意思,以后完善。
引用:
http://blog.csdn.net/pankun/article/details/598582
阅读(1410) | 评论(0) | 转发(0) |