Коллекция интерфейсов

Интерфейсы

//C has no interfaces, and these types know nothing about one
typedef struct {
    const char *name;
} Flower;

typedef struct {
    const char *title;
    int people;
} City;

typedef struct {
    const char *designation;
} Star;

//the interface Named lives outside the types:
//a pointer to an object and a table with the methods for its type
typedef struct {
    const char *(*getName)(const void *self);
} NamedOps;

typedef struct {
    const void *self;
    const NamedOps *ops;
} Named;

//one function and one table for each type
const char *flowerName(const void *self) {
    return ((const Flower *)self)->name;
}

const char *cityName(const void *self) {
    return ((const City *)self)->title;
}

const char *starName(const void *self) {
    return ((const Star *)self)->designation;
}

const NamedOps flowerOps = {flowerName};
const NamedOps cityOps = {cityName};
const NamedOps starOps = {starName};

Flower rose = {"Rose"};
City rome = {"Rome", 2800000};
Star sirius = {"Sirius"};

//objects of different types in one array
Named rows[] = {
    {&rose, &flowerOps},
    {&rome, &cityOps},
    {&sirius, &starOps},
};

char list[32] = "";
for (size_t i = 0; i < sizeof rows / sizeof rows[0]; i++) {
    if (i > 0) {
        strcat(list, ", ");
    }
    strcat(list, rows[i].ops->getName(rows[i].self));
}
//list is "Rose, Rome, Sirius"

printf("list is %s\n", list);