基本思想是创建一个可变大小的数组,在构建时固定,在单个分配单元中创建另一个类,以减少开销并提高效率。分配一个缓冲区以适应数组,另一个对象和放置 new 用于构造它们。为了访问数组和其他对象的元素,使用了指针算法和 reinterpret_cast。这似乎有效(至少在 gcc 中),但我对标准的阅读(5.2.10 Reinterpret Cast)告诉我这是一个未定义的行为。那是对的吗?如果是这样,有没有办法在没有 UB 的情况下实现这个设计?
完整的可编译示例在这里:http: //ideone.com/C9CCa8
// a buffer contains array of A followed by B, laid out like this
// | A[N - 1] ... A[0] | B |
class A
{
size_t index;
//...
// using reinterpret_cast to get to B object
const B* getB() const
{
return reinterpret_cast<const B*>(this + index + 1);
}
};
class B
{
size_t a_count;
//...
virtual ~B() {}
// using reinterpret_cast to get to the array member
const A* getA(size_t i) const
{
return reinterpret_cast<const A*>(this) - i - 1;
}
};
// using placement new to construct all objects in raw memory
B* make_record(size_t a_count)
{
char* buf = new char[a_count*sizeof(A) + sizeof(B)];
for(auto i = 0; i < a_count; ++i)
{
new(buf) A(a_count - i - 1);
buf += sizeof(A);
}
return new(buf) B(a_count);
}