我先给出我写的一个简单的sample再做进一步的说明:
#include
#include
struct A
{
int a;
};
struct B
{
struct A aaa;
int b;
};
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(char *)(address) - \
(unsigned long)(&((type *)0)->field)))
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
struct B *pb;
struct A aa;
aa.a = 1;
CONTAINING_RECORD(pb, struct B, aaa) = (struct B *)&aa;
printf("%d\n", pb->aaa.a);
return EXIT_SUCCESS;
}
程序的执行结果为 “1”,在windows上用的eclipse进行编辑,编译器用的Cygwin。
其实代码都很简单,我想主要讲解一下CONTAINING_RECORD 这个宏函数。这个函数是实现继承的重要的一步。
&((type *)0)->field))其实就是field到address 0的偏移量,再用address减去这个偏移量就得到了filed实际所在的位置。可能大家会对address为什么要转换为(char×)好奇。我先举一个例子:int ×a; a-1 移动了四个位置,那如果a是char×的话每一次移动的就是1个位置。这也就是上面要强制转换为char×的原因所在。
阅读(1474) | 评论(1) | 转发(0) |