JSON

C++小技巧之CONTAINING

字号+ 作者:H5之家 来源:H5之家 2017-04-20 09:04 我要评论( )

CONTAINING_RECORDContaining record是一个在C++编程中用处很大的一种技巧,它的功能为已知结构体或类的某一成员、对象中该成员的地址以及这一结构体名或类名,

CONTAINING_RECORD

Containing record是一个在C++编程中用处很大的一种技巧,它的功能为已知结构体或类的某一成员、对象中该成员的地址以及这一结构体名或类名,从而得到该对象的基地址。

由于写法简单,它被当做一个宏来使用,写法是这样的。

#define CONTAINING_RECORD(address,type,field) \

((type*)((PCHAR)(address)-(ULONG_PTR)(&((type*)0)->field)))

这个宏运用的是地址的偏移来实现的,这里我们需要补充一个知识点:

用type*来对0进行强制类型转换(type是一个结构体名或类名)再调用其成员后,该成员的地址就等于其相对于基地址的相对地址即偏移。

m_1; m_3; //0x8 }DATA,*PDATA; int main() { int* v3 = (int*)(&((PDATA)0)->m_2); printf(,v3); //最后输出结果为4,即m_2的相对地址。 }

明白了这个就更容易理解CONTAINING_RECORD的实现了,显然,该对象的绝对地址,就等于对象中某一个成员的绝对地址减去这一成员的相对地址。而刚刚我们计算的就是这一相对地址。(ULONG_PTR)(&((type*)0)->field))

(PCHAR)(address) 则是该成员的绝对地址,最后两个相减,就得到了对象的基地址,利用这个基地址可以做很多事情。

注意取地址之后的强制类型转换

最终的实现:

m_1; m_3; //0x8 }DATA,*PDATA; main() { DATA Data = {33,22,11}; //int* v3 = (int*)(&((PDATA)0)->m_1); int* v1 = &Data.m_2; PDATA v2 = CONTAINING_RECORD(v1, DATA, m_2); printf(, v2->m_1,v2->m_2,v2->m_3); ; } //最终v2就是对象Data的地址,我们可以不使用Data就直接访问该对象的成员

爱编程-编程爱好者经验分享平台

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
网友点评
=