首页 > 解决方案 > 避免使用固定大小数组模板的 C++ 设计模式

问题描述

在不允许动态内存分配的系统中(即不使用 std::vector 等),在不使用模板的情况下制作固定大小的缓冲区类的好方法是什么?

A 注意到由于重复代码生成,我的可执行文件大小开始变小。

目前我有一个与此类似的模式,请注意,Fifo 不一定是实际应用程序,只是一个简化示例。

template <int S>
class FixedSizeFifo
{
    private:
       std::array<uint8_t, S> mBuf;
    public:
       PushFunction() {...}
       PopFunction() {...}
};
FixedSizeFifo<1000> myTransmitFifo;
FixedSizeFifo<100> myReceiveFifo;

我的第一个明显的解决方案是先分配存储空间,然后将指针和大小传递给 Fifo 类,但它需要更多的初始化代码和指针管理等。

class FixedSizeFifo
{
    private:
       uint8_t * mBuf;
       size_t mBufSize;
    public:
       FixedSizeFifo() = delete; // And other copy constructors/operators
       FixedSizeFifo(uint8_t * buf, size_t s) : mBuf(buf), mBufSize(s) {}
       PushFunction() {...}
       PopFunction() {...}
};
std::array<uint8_t, 1000> txBuf;
auto myTransmitFifo = FixedSizeFifo(txBuf.data(), txBuf.size());
std::array<uint8_t, 100> rxBuf;
auto myReceiveFifo = FixedSizeFifo(rxBuf.data(), rxBuf.size());

对于像这样的固定大小的存储应用程序,还有哪些其他有趣的技术?

谢谢...

标签: c++templates

解决方案


此类问题有三种常见的解决方案。都有各自的优缺点:

1 - 模板您要传递给的类/函数(如上面的第一个示例)。根据模板实例化的数量和模板类的复杂性,这会带来代码膨胀的风险。确实可以使代码看起来简洁明了。

2 - 传递指针和大小(如上面的第二个示例) - 完全避免使用模板,但确实增加了管理指针的风险,但这些通常可以轻松缓解。可能与 C 代码兼容。

3 - 使用与 std::string_view(或嵌入式模板库中的 etl::array_view)或 std::span 类似的设计模式。基本上将指向已分配内存的指针及其大小包装在另一个对象中并将其传入。具有随后能够在传入的包装器上调用常用函数的优点。但是,您现在在调用代码中有第三步;创建内存,创建内存的包装器,使用包装器调用函数。


推荐阅读