我创建很多次我在代码中的许多地方使用类DataBuffer,所以它应该快速轻量级。此外,我使用各种缓冲区大小,所以为了减少内存分配,我写了这样的模板:
template<unsigned int T_buffer_size> class DataBuffer
{
public:
DataBuffer (const unsigned int &buffer_size);
char buffer [T_buffer_size];
const unsigned int buffer_size;
};
问题是,我必须复制DataBuffer对象几次。这就是为什么我想知道移动构造函数是否可以在这里提供帮助。有没有一种简单的方法可以在对象之间移动我的'缓冲'数组?
实现这个类很容易:
class DataBuffer
{
public:
DataBuffer (const unsigned int &buffer_size);
char *buffer;
const unsigned int buffer_size;
};
但是因为'buffer'是一个常规指针,所以访问存储在其中的数据需要更多时间......
答案 0 :(得分:2)
有没有一种简单的方法可以在对象*(
char buffer [T_buffer_size];
)之间移动'缓冲'数组?
否,你必须复制(通过你可以安全地使用非常快的memcpy(...)
作为它在堆栈上分配,而不是指针。
只有在堆上分配的指针/对象才能利用右值优化。
更新的 查看代码,您可以将其重写为:
template<unsigned int T_buffer_size> class DataBuffer
{
public:
DataBuffer ();
char buffer [T_buffer_size];
};
答案 1 :(得分:1)
但是因为'缓冲'是常规的 指针需要更多时间才能访问 存储在其中的数据......
我觉得你错了。访问堆上的数组不一定比访问堆栈上的数组慢,例如,真正的区别在于创建和销毁数组。
直接来说,你无法双管齐下(但请进一步阅读)。如果您的DataBuffer在堆上分配,它将为基于堆的分配和释放的开销付出代价,但您将能够浅层交换数据并实现类似移动构造函数(请参阅Alexandrescu的mojo作为一个简单的提议问题)。如果它在堆栈上分配数据,那么创建和销毁将非常快,但是必须深度复制数据,这可能有点贵(虽然memcpy非常快,对于char缓冲区来说非常好)。
但是,通过编写自己的内存分配器,您可以充分利用这两个方面。我只建议你这样做,如果你真的想把它付诸实践,并且在分析器的帮助下看到这是一个真正的瓶颈。我没有时间或空间在这里教你这个,但我必须警告你,它似乎不像写一个那样微不足道(以对齐为例)。
确定是选择第一个示例还是第二个示例应主要取决于您是否始终可以在编译时确定缓冲区大小。如果是这样,请转到第一个解决方案,因为它允许在堆栈或堆上分配缓冲区。您可以通过执行以下操作浅交换数据:
DataBuffer<some_size>* d1 = new DataBuffer<some_size>;
DataBuffer<some_size>* d2 = 0;
std::swap(d1, d2);
...或者对于更复杂的示例,您可以使用诸如boost :: shared_ptr。
之类的东西