首页 > 解决方案 > 嵌入式 C++:没有动态分配的动态类型?

问题描述

这是我的问题,简化:

    枚举 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();
    }

这就是我苦苦挣扎的地方:

这是我的限制:

我虽然关于:

有没有可以满足我需求的设计/模型?

谢谢!

标签: c++design-patternsembeddeddynamic-typingstatic-allocation

解决方案


在 C++ 中,内存分配和对象存在是两个独立的概念,尽管在大多数情况下您会同时处理这两个概念。但是,在您的情况下,您可能希望明确地将两者分开:

  1. 为任何对象创建足够的内存:

    char buf[N];    // N >= sizeof(T) for all T in your hierarchy
    
  2. 创建动物:

    new (buf) GreyHound(args);
    
  3. 摧毁现有的动物(并为另一个动物腾出空间):

    reinterpret_cast<Animal*>(buf)->~Animal();
    

也就是说,您获得存储作为容器对象的一部分,但您通过放置新和显式销毁来动态管理 Animal 对象的生命周期。

还有一点:您的内存还需要针对您在其中构造的所有类型正确对齐。您可以使用一些库辅助特性,例如std::aligned_storagestd::aligned_union来简化计算,尽管您可能仍需要做一些工作来计算大小和对齐方式。


作为一个完全独立的替代方案,您可以放弃多态类层次结构并使用 astd::variant代替。这在概念上是相似的,但在实现方面有些不同。这在概念上相似的原因是因为你有一组有界的类型,所以你不需要多态性来在运行时处理任意的、未知的派生类型。


推荐阅读