有没有一种很好的方法在C++中创建"拆分对象"?

Fre*_*pin 9 c++ embedded

首先让我说我正在为微控制器创建软件,因此RAM的使用很重要,将大量的const数据块放到非易失性(闪存)内存中是有意义的.

我想要实现的是找到一种在C++中创建"拆分"对象的好方法.举个例子,我们假设有一个字节的数据(读/写)和一个用于访问它的多字节"收据".假设"收据"是一个长字符串,它是一个文件名,并且它指向的媒体很慢,所以在内存中缓冲单个字节是有意义的,而不是在每个请求上实际读取它.

class Data
{
    uint8_t byte;
    bool valid;
    const char filename[128];
    uint8_t read()
    {
        if (!valid)
            performReallySlowRead(filename, &byte);
        valid = true;
        return byte;
    };
    void write(uint8_t new_value)
    {
        byte = new_value;
        performRealWriteToMedia(filename, byte);
        valid = true;
    };
}
Run Code Online (Sandbox Code Playgroud)

这种方法的明显问题是整个130字节最终在RAM中,而其中只有两个需要更改.所以我想出了一个分裂对象的想法:

class DataNonConst
{
    uint8_t byte;
    bool valid;
}

class DataConst
{
    const char filename[128];
    DataNonConst * const data;
}

static DataNonConst storage;
const DataConst holder("some_long_name_here", &storage);
Run Code Online (Sandbox Code Playgroud)

现在唯一的问题是,如果我想拥有几百个这样的分裂对象,那么创建它们的过程(因此创建两个对象并将第二个链接到第一个)会变得非常无聊和有问题......

所以问题是 - 是否有一些很好的方法可以使它更容易使用,最好是一个聪明的C++技巧或者一些模板魔术?那就是 - 如何使用单个语句创建链接在一起的两个对象,最好隐藏一个对象?我不认为宏解决方案是可行的,因为没有简单的方法来自动创建存储对象的名称...对象需要是相同的类型,因为我需要在其他地方嵌入指向这些对象的指针(一个函数处理写它们,其他只关心阅读)...我想到的所有解决方案要么使用虚拟接口到模板(所以你通过vtable指针使对象更大并且可能得到奖金模板-bloat)或导致巨大的模板膨胀......

编辑:

实际上整个问题的一部分可以简化为一个简单的问题 - 有没有办法将匿名变量"绑定"到C++中的成员字段?就像:

const ConstData holder("...", NonConstData()); // this object HAS TO be ROMable
Run Code Online (Sandbox Code Playgroud)

在上面的"一厢情愿"中,持有者是ROM中的const对象,它有一个指针/引用/无论是在RAM中创建的"某处"的匿名对象NonConstData.要么:

std:pair<const ConstData &, NonConstData &> holder(ConstData(), NonConstData());
Run Code Online (Sandbox Code Playgroud)

任何允许我不要手动创建两个对象并将它们绑定到另一个对象的东西.

das*_*ght 2

您可以用整数替换指针,并为所有DataNonConst对象创建一个静态数组,如下所示:

class DataNonConst {
    uint8_t byte;
    bool valid;
};

static DataNonConst storages[MAX_DATA];

class DataConst {
    const char filename[128];
    const int dataIndex;
    DataNonConst *data() {
        return &storages[dataIndex];
    }
};

const DataConst holderOne("first_long_name_here", 0);
const DataConst holderTwo("second_long_name_here", 1);
const DataConst holderThree("third_long_name_here", 2);
Run Code Online (Sandbox Code Playgroud)

这种方法的灵感来自享元模式,尽管显然它在这里用于不同的目的。

这样做的一个明显的缺点是您需要手动计算条目以避免重复。但是,只有一个storages对象,因此无需创建其他对象。