Drawing various types of shapes I did the following Excercise:


  simulate single inheritance in C. Let each "base
     class" contain a pointer to an array of pointers to functions (to simulate
     virtual functions as freestanding functions taking a pointer to a "base
     class" object as their first argument). Implement "derivation" by
     making the "base class" the type of the first member of the derived class.
  
  For each class, initialize the array of "virtual functions" appropriately. To test the ideas, implement a version of "the old Shape example" with the base
  and derived draw() just printing out the name of their class. Use only
  language features and library facilities available in standard C.


I wonder if my approach is good? And as a side question: Is OOP relevant in practice with using c?

Edit: the goal is to simulate c++ like OOP constructs with the limited features of c.

#include &lt;stdio.h&gt;

typedef void(*pfct)(struct Shape*);

typedef struct {
    pfct draw;
}Vtable;

typedef struct{                 // "Base class"
    Vtable* pvtable;
}Shape;

typedef struct{                 // "Derived" from Shape
    Shape shape;
    int radius;
}Circle;

void draw(Shape* this)          // "Virtual function"
{
    (this-&gt;pvtable-&gt;draw)(this);
}

void draw_shape(Shape* this)    
{
    printf("Drawing Shape\n");
}

void draw_circle(Shape* this)
{
    Circle* pcircle = (Circle*)this;
    printf("Drawing Circle with radius = %i\n",pcircle-&gt;radius);
}

Shape* init_shape()
{
    Shape* pshape = malloc(sizeof(Shape));
    Vtable* pvtable = malloc(sizeof(Vtable));
    pvtable-&gt;draw = &amp;draw_shape;        
    pshape-&gt;pvtable = pvtable;
    return pshape;
}

Circle* init_circle(int radius)
{
    Circle* pcircle = malloc(sizeof(Circle));
    pcircle-&gt;shape = *init_shape();
    pcircle-&gt;shape.pvtable-&gt;draw = &amp;draw_circle;
    pcircle-&gt;radius = radius;
    return pcircle;
}

int main()
{
    Shape* myshape = init_shape();
    Circle* mycircle = init_circle(5);
    draw(myshape);
    draw(mycircle);

    getchar();
    return 0;
}
Simulate single inheritance in c
  I wonder if my approach is good?


Function consistency

I'd expect ..._circle(Shape* this) functions to take Circle* this.  Let the draw() play with the pointer conversions.

void draw(void* this) {
  Shape* pthis = this;
  (pthis-&gt;pvtable-&gt;draw)(pthis);
}

void draw_circle(Circle* this) {
    printf("Drawing Circle with radius = %i\n",this-&gt;radius);
}

// No longer generate a warning
draw(mycircle);


Naming convention

For type Shape, code uses ..._shape, the undefined struct Shape and  Vtable.  I'd expect greater uniformity - perhaps Shape_init(), Shape_draw(), Shape_Vtable, etc.

For Circle, use Circle_draw(), Circle_init(), etc. and not ..._circle().

Avoid text case changes.

Avoid anonymous struct Shape

This problem hints that code is using C++ to compile C code.  Best to use C for C code. 

Change typedef void(*pfct)(struct Shape*); to typedef void(*pfct)(Shape*); and move after typedef struct{ ... }Shape;

Missing companion free()

A companion to ..._init(), a ..._uninit() should exist.

Organization

Put Shape code in one place (or file) and Circle in another.



Consider allocating to the object, not the type

It is easier to code right, review and maintain.

// pshape = malloc(sizeof(Shape));
pshape = malloc(sizeof *pshape);


Error checking

Robust code checks memory allocation.

pshape = malloc(sizeof(Shape));
if (pshape == NULL) Handle_OutOfMemory();