嵌入式 C++:没有动态分配的动态类型?

embedded c++ : dynamic typing without dynamic allocation?

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

    enum AnimalType_t
    {
                DOG                         = 0,
                GREY_HOUND                  = 1,
                IMMORTAL_JELLYFISH          = 2,
    };
    struct RawData_t
    {
        int             age;
        AnimalType_t    typeOfAnimal;
    };

    RawData_t GetMyCurrentRawData();//returns the current raw data
    bool      IsDataReady(); //returns true if data is ready, false otherwise
    class Animal
    {
    public:
        virtual Animal();
        virtual ~Animal();
        int GetType() { return rawAttributes.typeOfAnimal; };   //the only implementation for all children
        virtual int GetAge() { return rawAttributes.age; };     //to be implemented in the child class
        virtual void UpdateAge() { rawAttributes.age++; };  //to be implemented in the child class
        virtual int GetNumberOfLegs() = 0;                      //to be implemented in the child class
    private:
        RawData_t rawAttributes;
    }
    class Dog : public Animal
    {
    public:
        Dog(RawData rawData):Animal(rawData){};
        int GetNumberOfLegs() {return 4;};                  
    };

    class GreyHound : public Dog
    {
    public:
        GreyHound(RawData rawData):Dog(rawData){};
    };

    class ImmortalJellyFish : public Animal
    {
    public:
        ImmortalJellyFish(RawData rawData):Animal(rawData){};
        int GetNumberOfLegs() {return 0;};      
        void UpdateAge() { return;} override;
    };
    class Building
    {
    public:
        Building(){};
        //sorry for the long line, but you get the idea...
        int Display(void){if(IsDataReady()) DisplayOnScreen("This animal ( "+ animal_m.GetType()+") has " + animal_m.GetNumberOfLegs() + "legs and is " + animal_m.GetAge() + " years old\n";};
        int Live(void){currentDiagCode_m.UpdateAge();};

    private:
        auto                        animal_m; //?? not working
    };

    static Building paddock;
    static Building farm;

    void Buildings_Step(void)
    {
        paddock.Live();
        paddock.Display();
        farm.Live();
        farm.Display();
    }

这是我挣扎的地方:

这是我的限制条件:

我想:

有什么design/model可以满足我的需求吗?

谢谢!

在 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 来简化计算,但您可能仍需要做一些工作来计算大小和对齐方式。


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