C++
std::numeric_limits<UInt32>::max()
placement new
用于控制分配空间
cpp
PostingListInMemory * posting_list = arena.alloc<PostingListInMemory>();
new (posting_list) PostingListInMemory();
cpp
/// placement new;
PostingListInMemory & operator=(const PostingListInMemory & other)
{
if (this != &other)
{
this->~PostingListInMemory();
if (other.m.set.type != 0)
new (&m.bitmap) roaring::Roaring(other.m.bitmap);
else
new (&m.set) PostingListSet(other.m.set);
}
return *this;
}
PostingListInMemory * local_posting_list = external_posting_list;
if (!local_posting_list)
{
local_posting_list = arena.alloc<PostingListInMemory>();
new (local_posting_list) PostingListInMemory();
}
slignas union
cpp
struct alignas(8) PostingListInMemory
{
union M
{
PostingListSet set;
roaring::Roaring bitmap;
M() : set() {}
~M()
{
if (set.type != 0)
bitmap.~Roaring();
}
} m;
这段代码定义了一个名为 PostingListInMemory 的结构体,其中包含了一个匿名联合体(union)M。在C++中,联合体是一种特殊的数据结构,它允许在相同的内存位置存储不同的数据类型,但同一时间只能存储其中的一种类型。
联合体 M
的定义
联合体 M 包含了两个成员:
-
PostingListSet set;
-
roaring::Roaring bitmap;
并且有一个构造函数和一个析构函数。
联合体的作用
在这个上下文中,联合体 M 允许 PostingListInMemory 结构体在相同的内存位置存储两种不同类型的数据结构,即 PostingListSet 和 roaring::Roaring。这意味着 PostingListInMemory 的实例可以根据需要在两种表示方法之间切换,而不需要额外的内存开销。
构造函数和析构函数
构造函数 M()
:初始化联合体的 set 成员。
析构函数 ~M()
:这是一个自定义的析构函数,它的目的是确保在销毁 M 联合体时,正确地调用所存储对象的析构函数。这里使用了一个条件判断 if (set.type != 0) 来检查当前联合体中存储的是哪个对象。如果 set.type 不为0,这意味着 set 成员被使用过,因此需要显式调用 bitmap 的析构函数。这种做法是为了避免在销毁时调用错误的析构函数,因为联合体中的成员共享内存空间。
注意事项
这种使用联合体和条件析构的做法是比较底层的操作,需要对内存管理和对象生命周期有深入的理解。
在现代C++中,通常推荐使用智能指针或其他RAII(Resource Acquisition Is Initialization)技术来管理资源,以避免这类复杂的内存管理问题。
此外,alignas(8) 指令确保了整个 PostingListInMemory 结构体按8字节对齐,这可能是为了优化性能或满足某些硬件平台的要求。
总之,这段代码展示了一种在C++中使用联合体来实现类型双关(type punning)的方法,允许在相同的内存位置存储和使用两种不同的数据结构。