c++ - 嵌入式 C++:没有动态分配的动态类型?
问题描述
这是我的问题,简化:
- 我有一个 C/C++ 代码,C 用于服务,C++ 用于处理。
- 我在 C 中有一个接口,它返回一个结构 RawData,其中包含循环更新的信息。
枚举 AnimalType_t { 狗 = 0, GREY_HOUND = 1, IMMOTAL_JELLYFISH = 2, }; 结构 RawData_t { 年龄; AnimalType_t typeOfAnimal; }; RawData_t GetMyCurrentRawData();//返回当前原始数据 布尔 IsDataReady(); //如果数据准备好返回true,否则返回false
- 我有一个虚拟妈妈班“动物”
动物类 { 上市: 虚拟动物(); 虚拟~动物(); int GetType() { return rawAttributes.typeOfAnimal; }; //所有孩子的唯一实现 virtual int GetAge() { return rawAttributes.age; }; //在子类中实现 虚拟 void UpdateAge() { rawAttributes.age++; }; //在子类中实现 虚拟 int GetNumberOfLegs() = 0; //在子类中实现 私人的: RawData_t rawAttributes; }
- 我有一个从母亲类继承的已知动物列表。
类狗:公共动物 { 上市: 狗(RawData rawData):动物(rawData){}; int GetNumberOfLegs() {返回 4;}; }; 灰狗类:公共狗 { 上市: GreyHound(RawData rawData):Dog(rawData){}; }; 类 ImmortalJellyFish : 公共动物 { 上市: ImmortalJellyFish(RawData rawData):Animal(rawData){}; int GetNumberOfLegs() {返回 0;}; 无效 UpdateAge() { return;} 覆盖; };
- 我有一个“建筑”类,其中只有一个动物,但在实例化建筑物时我不知道它的类型。
类建筑 { 上市: 建造(){}; //对不起,排长队,但你明白了...... int Display(void){if(IsDataReady()) DisplayOnScreen("这个动物 ("+ animal_m.GetType()+") 有 " + animal_m.GetNumberOfLegs() + "腿并且是 " + animal_m.GetAge() + "岁\n";}; int Live(void){currentDiagCode_m.UpdateAge();}; 私人的: 自动动物_m;//?? 不工作 }; 静态建筑围场; 静态建筑农场; 无效建筑物_步骤(无效) { 围场.Live(); 围场.Display(); 农场.Live(); 农场.Display(); }
这就是我苦苦挣扎的地方:
- 在建筑物实例化期间为建筑物中的动物分配内存而不知道其类型,
- 动物的类型和属性可能会周期性地变化 换句话说:静态分配的动态类型是否可能?那么,我怎样才能调用这些实例以便调用正确的方法呢?
这是我的限制:
- 嵌入式系统
- 没有动态内存分配
我虽然关于:
- 具有 unique_ptr 的工厂设计模式效果很好!!!...但是,在堆上:(
- 对象池?
- 动态类型:但没有动态分配是不可能的,是吗?
有没有可以满足我需求的设计/模型?
谢谢!
解决方案
在 C++ 中,内存分配和对象存在是两个独立的概念,尽管在大多数情况下您会同时处理这两个概念。但是,在您的情况下,您可能希望明确地将两者分开:
为任何对象创建足够的内存:
char buf[N]; // N >= sizeof(T) for all T in your hierarchy
创建动物:
new (buf) GreyHound(args);
摧毁现有的动物(并为另一个动物腾出空间):
reinterpret_cast<Animal*>(buf)->~Animal();
也就是说,您获得存储作为容器对象的一部分,但您通过放置新和显式销毁来动态管理 Animal 对象的生命周期。
还有一点:您的内存还需要针对您在其中构造的所有类型正确对齐。您可以使用一些库辅助特性,例如std::aligned_storage
或std::aligned_union
来简化计算,尽管您可能仍需要做一些工作来计算大小和对齐方式。
作为一个完全独立的替代方案,您可以放弃多态类层次结构并使用 astd::variant
代替。这在概念上是相似的,但在实现方面有些不同。这在概念上相似的原因是因为你有一组有界的类型,所以你不需要多态性来在运行时处理任意的、未知的派生类型。
推荐阅读
- android - 例如,如何关闭和应用程序。减少 20 分钟
- python-3.7 - 我正在尝试在 python 中创建 cookie 点击器。我已经实现了一个自动点击器,但是,每次我点击它都会添加另一个自动点击器
- html - css网格上没有边距/填充底部?
- php - 如何使用 Laravel 5 将嵌套对象插入 MongoDB?
- javascript - 如何仅显示具有指定值的条目的对象键
- rebus - Rebus 2 级重试
- c# - 我在哪里可以在可移植可执行文件的标头中找到 IMAGE_LOAD_CONFIG_DIRECTORY 结构?
- java - 如何使用 okhttp3 制作登录页面
- python - NumPy hstack 的奇怪行为
- laravel - 模型事件未在 laravel 上触发