C ++中固定大小数组的池分配器

时间:2013-10-20 08:45:03

标签: c++ arrays templates c++11 allocation

我为我的嵌入式MCU项目做了一个非常简单的池分配器。这是一个带有以下界面的模板类(跳过实现部分,如果有人有兴趣,我也可以发布它):

template <typename T, size_t size>
class SimplePoolAllocator
{
public:
    SimplePoolAllocator();
    T * allocate();
    void deallocate(T *pointer);
...
}

它非常适用于类或POD等“简单”事物,例如:

SimplePoolAllocator<double, 10> poolOfDouble; // returns "double *"
SimplePoolAllocator<WeirdClass, 5> poolOfObjects; // returns "WeirdClass *"

如果我想将它用于固定大小的数组,则会出现问题。这个用途当然是原始数据缓冲区 - 在我的项目中我有两个“传输”类型,一个有16个字节,另一个有100个。

所以假设我使用这样的话:

SimplePoolAllocator<uint8_t[16], 10> pool1;
SimplePoolAllocator<uint8_t[100], 10> pool2;

一切似乎都很好,但问题是现在allocate()返回类似于:“uint8_t(*)[16]”和“uint8_t(*)[100]”。理想情况下,我希望在这种情况下只返回“uint8_t *”(指向开头)。

我知道我可以这样做:

uint8_t *p = *pool1.allocate(); // additional asterisk to "drop" the array thing from the type

但这看起来......很奇怪......

所以问题是 - 如何改进我的SimplePoolAllocator接口(或任何东西)以支持简单分配“普通”对象(如上所示 - 类和POD)和固定大小的数组,但只返回指向第一个的指针元件?可以不使用std :: array并使用它的data()成员函数,或者没有额外的'*'来完成它吗? C ++ 11的功能对我来说还可以,如果会有“转换”这样的类型,它可以在这里保存我:WeirdClass - &gt; WeirdClass *,uint8_t [16] - &gt; uint8_t *。我无法轻松地将缓冲区包装在类中,因为我以“原始”形式处理中断传输 - 我需要的是指向缓冲区的指针,稍后通过消息队列传递给任务进行处理,使用“type”( size)作为消息的一个要素。如果可能的话,我想避免使用虚函数来完成这个简单的任务(;

它可以完成,或者我可能要求太多了?也许唯一的解决方案是使模板的接口像这样:

template <typename T, size_t array_size, size_t size>

所以我有:

SimplePoolAllocator<WeirdClass, 1, 10> pool1;
SimplePoolAllocator<uint8_t, 16, 10> pool2;

但这看起来也不太好......

提前thx任何建议!请注意,这个问题是关于微控制器的一个项目,所以使用Boost或类似的东西是不可能的。

1 个答案:

答案 0 :(得分:4)

你应该专攻你的课程:

template <typename T, size_t size>
class SimplePoolAllocator
{
public:
    SimplePoolAllocator();
    T * allocate();
    void deallocate(T *pointer);
...
};

template <typename T, size_t N, size_t size>
class SimplePoolAllocator<T[N],size> // <-- here
{
public:
    SimplePoolAllocator();

    // you can now use different signatures and different implementations:
    T ** allocate();
    void deallocate(T **pointer);
...
};

这可能是分离这些案件并独立对待它们的最简单方法。