我处于不幸的位置,编写自己的矢量实现(不,很遗憾,使用标准实现是不可能的)。现在使用的那个使用原始字节缓冲区和就地构造和对象的解构,但作为副作用,我无法查看实际元素。所以我决定做一个使用内部真实数组的变体实现。
在处理它时,我注意到分配数组会导致额外调用construtor和析构函数,并将其映射到原始缓冲区版本。在不丢失阵列访问权限的情况下,这种开销是否可以避免?如果它与原始缓冲区版本一样快,那就太好了,所以可以替换它。
如果有人知道一个很好的实现方式我也可以自己开发,或者至少从中得到一些想法,我也很感激。毕竟这项工作非常棘手。 :)
编辑:
一些代码可以更好地解释它。
T* data = new T[4]; // Allocation of "num" elements
data[0] = T(1);
data[1] = T(2);
delete[] data;
现在,对于数组的每个元素,都调用了默认构造函数,然后调用了2个赋值方法。因此,只有2个构造函数调用,我们有4个和后来的4个析构函数调用,而不是2个。
答案 0 :(得分:2)
作为副作用,我无法查看实际的元素。
为什么不呢?
void* buffer = ...
T* elements = static_cast<T*>(buffer);
std::cout << elements[0] << std::endl;
答案 1 :(得分:2)
使用true数组意味着将调用构造函数。你需要转到原始字节缓冲区 - 但这并不算太糟糕。假设你有一个缓冲区:
void *buffer;
将其更改为T *
:
T *buffer;
分配时,将其视为原始内存缓冲区:
buffer = (T *) malloc(sizeof(T) * nelems);
并根据需要调用构造函数:
new(&buffer[x]) T();
您的调试器应该能够像使用真实数组一样查看缓冲区的元素。当需要释放数组时,当然,你有责任释放数组的元素,然后将其传递给free()
:
for (int i = 0; i < nInUse; i++)
buffer[x].~T();
free((void*)buffer);
请注意,我不会使用new char[]
和delete[]
来分配此数组 - 我不知道new char[]
是否会正确对齐,无论如何您需要在char*
数组之前,请小心转回delete[]
。
答案 2 :(得分:1)
我发现以下实现非常有趣:C Array vs. C++ Vector
除了性能比较之外,他的矢量实现还包括向量上的推/弹操作。
The code还有一个显示如何使用宏的示例:
#include "kvec.h"
int main() {
kvec_t(int) array;
kv_init(array);
kv_push(int, array, 10); // append
kv_a(int, array, 20) = 5; // dynamic
kv_A(array, 20) = 4; // static
kv_destroy(array);
return 0;
}