C++获取条目的结构
C++ get struct for an entry
我在C++中学习数据结构和算法时遇到以下代码。它来自https://github.com/xtaci/algorithms/blob/master/include/double_linked_list.h线194到206。
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#ifndef _MSC_VER
#define list_entry(ptr, type, member)
(reinterpret_cast<type *>((char *)(ptr)-(char *)(&(reinterpret_cast<type *>(1)->member))+1))
#else
#define list_entry(ptr, ptrtype, member)
(reinterpret_cast<ptrtype>((char *)(ptr)-(char *)(&(reinterpret_cast<ptrtype>(1)->member))+1))
#endif
注释块表示这个Marco的功能是获取这个条目的结构。令我困惑的是的使用
reinterpret_cast<type *>(1)->member
将1转换为(类型*(并访问其成员是什么意思?
*感谢您提前提供的帮助。如果有任何部分不清楚,我会迅速编辑*
*更多信息*:
这个Marco在代码中用于定义新的Marco
#define list_for_each_entry_safe(pos, n, head, member)
for (pos = list_entry((head)->next, typeof(*pos), member),
n = list_entry(pos->member.next, typeof(*pos), member);
&pos->member != (head);
pos = n, n = list_entry(n->member.next, typeof(*n), member))
新马可的用法示例来自https://github.com/xtaci/algorithms/blob/master/include/graph_defs.h第45至51行作为析构函数的一部分。
struct Adjacent {
struct Vertex v;
int32_t color; // color for searching
int32_t d; // discover time
int32_t f; // finish time
struct list_head v_head; // vertex list header
struct list_head a_node;
uint32_t num_neigh; // num of neighbours
Adjacent(uint32_t id):v(id) {
INIT_LIST_HEAD(&v_head);
num_neigh = 0;
}
~Adjacent() {
Vertex * v, *vn;
list_for_each_entry_safe(v, vn, &v_head, v_node){
list_del(&v->v_node);
delete v;
}
}
......
&(reinterpret_cast<type *>(1)->member)
如果类似于Macro offsetof
,则使用此语句获取结构中成员的偏移地址。
棘手的reinterpret_cast<type *>(1)
告诉编译器有一个地址为0x1
的type *
指针,然后&(reinterpret_cast<type *>(1)->member)
得到成员的偏移地址加上原始的0x1
我用下面的代码来验证它。
struct list_head {
struct list_head *next, *prev;
};
struct Vertex {
int x;
int y;
list_head v_node;
};
int main()
{
Vertex *v = (Vertex *) malloc(sizeof(Vertex));
printf("%p", &(reinterpret_cast<Vertex *>(1)->v_node));
return 0;
}
它打印0x9
,确切地说是2*sizeof(int) + 1
我个人认为使用1
而不是0
可以避免编译器将其视为无效的NULL指针。因此,在宏中,1
在尾部再次为正。
宏list_entry
可以像这个一样使用
int main()
{
Vertex *v = (Vertex *) malloc(sizeof(Vertex));
Vertex *w = list_entry(&(v->v_node), Vertex, v_node);
printf("%pn%pn", v, w);
return 0;
}
当我们只有指向list_head
的指针时,我们可以使用list_entry
来获取外部结构。在上述代码中,v
和w
指向同一区域。
相关文章:
- 从字符串中获取结构的大小
- 如何在结构初始化中获取成员C++
- 从 cin 获取 c++ 中结构中多个枚举的输入
- 如何通过向量中的结构 id 获取索引号
- 获取结构 c++ 中元素的索引
- 如何获取结构C++的输入
- 使用加速融合获取结构名称
- 如何使用值获取结构的索引
- 如何获取结构体成员的地址
- 结构化绑定,无需复制即可获取子向量的连续元素
- 在通过 P/Invoke 获取的 C++ 结构上设置 C# 回调
- 获取指向映射内结构的指针
- 从行分析中获取结构
- 在模板实例化期间获取原始结构/类名C++
- 如何从 GIFLIB 保存图像结构中获取 RGB 颜色数据
- 获取结构的 UUID
- 如何直接从 FILETIME 结构获取/设置和获取秒数
- 从知道其结构类型的实例中获取值
- 如何使用结构C++获取从函数中生成的最大值
- 从接口层次结构获取接口