关于设计模式:嵌入式c ++:没有动态分配的动态类型?

embedded c++ : dynamic typing without dynamic allocation?

这是我的问题,简化了:

  • 我有一个C/C++的代码,C用于服务,C++用于处理。
  • 我在C中有一个接口,它返回一个包含循环更新信息的结构rawdata。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    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
  • 我有一个虚拟的母亲班"动物"
1
2
3
4
5
6
7
8
9
10
11
12
    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;
    }

  • 我有一份从母亲阶级继承下来的动物名单。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    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;
    };
  • 我有一个类"建筑",其中有一个,只有一个,动物,但我不知道它的类型,当我实例化的建筑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    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
"
;};
        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();
    }

我在这里挣扎:

  • 为建筑中的动物分配内存,在建筑实例化期间不知道其类型,
  • 动物的类型和属性可能会周期性地改变。换句话说:动态类型和静态分配是可能的吗?那么,如何调用这些实例才能调用正确的方法呢?

以下是我的限制条件:

  • 嵌入式系统
  • 没有动态内存分配

我认为:

  • 工厂设计模式与独特的_-ptr,这是伟大的工作!!!!…但是,在堆上:(
  • 对象池?
  • 动态类型:但是没有动态分配是不可能的,是吗?

有什么设计/模型可以满足我的需求吗?

谢谢您!


在C++中,内存分配和对象存在是两个独立的概念,即使在大多数情况下,两者都将一起处理。不过,在您的情况下,您可能希望明确地将这两个部分分开:

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

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

    1
    new (buf) GreyHound(args);

  • 摧毁现有动物(并为其他动物腾出空间):

    1
    reinterpret_cast<Animal*>(buf)->~Animal();
  • 也就是说,您可以获得作为容器对象一部分的存储,但是您可以通过放置新的和显式的销毁动态地管理动物对象的生存期。

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

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