这是我的问题,经过简化:

  • 我在C / C++中有一个代码,C用于服务,C++用于处理。
  • 我在C语言中有一个接口(interface),该接口(interface)返回一个结构RawData,该结构包含周期性更新的信息。

  • 枚举AnimalType_t
    {
    狗= 0,
    GREY_HOUND = 1
    IMMORTAL_JELLYFISH = 2
    };
    结构RawData_t
    {
    年龄
    AnimalType_t typeOfAnimal;
    };

    RawData_t GetMyCurrentRawData(); //返回当前原始数据
    bool IsDataReady(); //如果数据准备就绪,则返回true,否则返回false
  • 我有一个虚拟的母类“动物”

  • 动物类
    {
    上市:
    虚拟Animal();
    虚拟〜Animal();
    int GetType(){return rawAttributes.typeOfAnimal; }; //所有子代的唯一实现
    虚拟int GetAge(){return rawAttributes.age; }; //要在子类中实现
    虚拟void UpdateAge(){rawAttributes.age ++; }; //要在子类中实现
    虚拟int GetNumberOfLegs()= 0; //要在子类中实现
    私有(private)的:
    RawData_t rawAttributes;
    }
  • 我有一个已知的动物列表,这些动物是从母系继承的。

  • 狗类:公共(public)动物
    {
    上市:
    Dog(RawData rawData):动物(rawData){};
    int GetNumberOfLegs(){return 4;};
    };

    GreyHound类:公犬
    {
    上市:
    GreyHound(RawData rawData):Dog(rawData){};
    };

    类ImmortalJellyFish:公共(public)动物
    {
    上市:
    ImmortalJellyFish(RawData rawData):Animal(rawData){};
    int GetNumberOfLegs(){返回0;};
    void UpdateAge(){return;}覆盖;
    };
  • 我有一类“建筑物”,其中只有一种动物,但是在实例化建筑物时我不知道它的类型。

  • 类 build
    {
    上市:
    建造(){};
    //很抱歉排长队,但您知道了...
    int Display(void){if(IsDataReady())DisplayOnScreen(“此动物(” + animal_m.GetType()+“)具有” + animal_m.GetNumberOfLegs()+“腿,并且是” + animal_m.GetAge()+“岁\ n“;};
    int Live(void){currentDiagCode_m.UpdateAge();};

    私有(private)的:
    auto animal_m; // ??不工作
    };

    静态建筑围场;
    静态建筑农场;

    无效的Buildings_Step(无效)
    {
    paddock.Live();
    paddock.Display();
    farm.Live();
    farm.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_storagestd::aligned_union之类的一些库帮助程序特征来简化计算,尽管您可能仍需要做一些工作来计算大小和对齐方式。

    作为完全独立的替代方法,您可以放弃多态类的层次结构,而改为使用std::variant。这在概念上相似,但在实现方式上有所不同。从概念上讲,这是相似的原因是因为您有一组有限的类型,所以您实际上不需要多态即可在运行时处理任意的,未知的派生类型。

    10-06 09:31