【发布时间】:2020-12-05 10:04:56
【问题描述】:
我为一个有按钮和灯的控制器编写了代码。它基于 Arduino/ATmega2560。 RAM非常有限。无法更改为其他设备。
每个按钮和灯都被建模为一个 C++ 类实例。它们派生自抽象类Thing,其中包含一个指针mpTarget,指示Things 之间的连接。目标最初是在运行时分配的,在运行时不会更改。
我需要节省内存。因为我有大约 600 个 Things,如果所有这些 mpTargets 都存储在 ROM(而不是 RAM)中,这将对我有很大帮助,因为目标在编译时是已知的。
所以我玩了constexpr。但是,似乎不可能只部分地创建一个类constexpr。我无法创建整个类constexpr,因为还有一些成员变量在运行时会发生变化(下例中的mState)。
什么是实现这种行为的好方法?常量表达式?模板?有什么事吗?
澄清
-
我知道
mpTarget当前是在运行时初始化的。但是每个目标在编译时都是已知的,这就是为什么我想找到一种保存这些指针的 RAM 字节的好方法。 -
我真的不想离开面向对象的设计。我之前使用了一种简单的“普通旧”数据类型的方法(实际上消耗的 RAM 更少)。但由于此代码的开发仍在进行中(添加/删除/修改类和实例),很有可能会错过必要的修改,从而引入难以发现的错误。
-
对于这个项目,只为
mpTarget保存 RAM 存储就绰绰有余了。保持 vtable 指针的开销很好。我真正在寻找的是——正如标题所暗示的——一种我们如何实现一个其成员是部分constexpr的类的方法。我也想过使用模板,但没有成功。
示例代码
#include <iostream>
class Thing
{
public:
// only called in setup()
void setTarget(Thing & pTarget)
{
mpTarget = & pTarget;
}
virtual void doSomething(int value) {};
protected:
// known at compile time - can we make this constexpr?
Thing * mpTarget;
};
class Button : public Thing
{
public:
void setState(int newState)
{
mState = mState + newState;
mpTarget->doSomething(mState);
}
private:
// changes during runtime
int mState;
};
class Lamp: public Thing
{
public:
virtual void doSomething(int value)
{
std::cout << value << std::endl;
};
};
Button myButton;
Lamp myLamp;
int main()
{
myButton.setTarget(myLamp);
while (1)
{
myButton.setState(123);
}
}
【问题讨论】:
-
变量是存储在 RAM 还是 ROM 中,不能完全由
constexpr说明符控制。因此,它会使前提变弱,否则是一个很好的问题。 -
这能回答你的问题吗? g++ compiler flag to minimize binary size EDIT 我现在意识到你想要做的是不同的。无论如何,我在那里链接的问题的上下文可能对您来说很有趣,所以我将其留在这里。
-
您如何创建/初始化您的 600
Things? -
@Mat - 我像上面的例子一样初始化所有东西。全局范围内的 600 个实例,无参数。然后,在运行时开始时,为每个实例调用 setTarget()。
-
@Mat - 你是对的 - 有很多闪存,我只使用了 20% 的闪存,但使用了 ATmega 的 8k RAM 的 80%。