Помогите переписать с c++ на с абстрактный и наследуемые классы

Помогите переписать часть кода с c++ на си. Есть абстрактный класс

class Shape
   {
    public:
    virtual void Draw() = 0;
    virtual int  GetArea() = 0;
     protected:
     int Tmk(int h);
     int  x;
     int y;           
   }

и 2 наследуемых класса

class Rectangle: public Shape
    { 
    public: 
       void Draw()
     {
    cout << "Rectangle" <<  endl;
  }
    private:
    int k;
   }

class Circle: public Shape

    {
    public:
    int GetArea()
    {
      return 6;
    }
    private:
    int z;
    };

В функции создаются объекты данных классов следующим образом:

Shape* shape;
if(...)
{
   shape = new Rectangle();
}
else if(...)
{
   shape = new Circle();
}

Как переписать данный код на С, чтобы потом была возможность из объекта класса shape получить доступ к методам и членам разных классов, например,

    ((shape*)figure)->Draw();

и выводилось "Rectangle"?


Ответы (1 шт):

Автор решения: avp

Что-то в таком духе

typedef void (*Draw)(void *);

enum shape_type {
  RECTANGLE, CIRCLE, TRIANGLE
};

struct Shape {
  enum shape_type type; // на пракике я бы добавил ...
  Draw draw;

  int x, y;
};

struct Rectangle {
  struct Shape base;
  int k;
};

void draw_rect (void *p)
{
  printf("Rectangle %d\n", ((struct Rectangle *)p)->k);
}

void *Rectangle (int k)
{
  struct Rectangle *p = calloc(sizeof(*p), 1);
  p->base.type == RECTANGLE;
  p->base.draw = draw_rect;
  p->k = k;

  return p;
}


int
main(int ac, char *av[])
{
  struct Shape *shape = Rectangle(10);

  shape->draw(shape);

  return puts("End") == EOF;
}

Для Circle и других фигур аналогично.

Private, protected (и проч.), естественно, не моделируем.

Существенное упрощение, вызывающее лишний расход памяти, это указатели на функции "класса наследника" в каждом экземпляре фигуры.

В принципе, их (указатели на фукции) можно было бы бы хранить в отдельной статической структуре (одной на каждый тип фигуры), но 1) синтаксис p->f() тут уже не реализуешь... 2) много будет возни с макросами (скорее всего оно того просто на стоит ... -)).

→ Ссылка