Это зависит от того, какой именно «объектно-ориентированный» набор функций вы хотите иметь. Если вам нужны такие вещи, как перегрузка и / или виртуальные методы, вам, вероятно, нужно включить указатели на функции в структуры:
typedef struct {
float (*computeArea)(const ShapeClass *shape);
} ShapeClass;
float shape_computeArea(const ShapeClass *shape)
{
return shape->computeArea(shape);
}
Это позволит вам реализовать класс, «наследуя» базовый класс и реализуя подходящую функцию:
typedef struct {
ShapeClass shape;
float width, height;
} RectangleClass;
static float rectangle_computeArea(const ShapeClass *shape)
{
const RectangleClass *rect = (const RectangleClass *) shape;
return rect->width * rect->height;
}
Это, конечно, требует, чтобы вы также реализовали конструктор, который обеспечивает правильную настройку указателя функции. Обычно вы выделяете память для экземпляра динамически, но вы также можете позволить вызывающей стороне сделать это:
void rectangle_new(RectangleClass *rect)
{
rect->width = rect->height = 0.f;
rect->shape.computeArea = rectangle_computeArea;
}
Если вам нужно несколько разных конструкторов, вам придется «украсить» имена функций, у вас не может быть более одной rectangle_new()
функции:
void rectangle_new_with_lengths(RectangleClass *rect, float width, float height)
{
rectangle_new(rect);
rect->width = width;
rect->height = height;
}
Вот базовый пример использования:
int main(void)
{
RectangleClass r1;
rectangle_new_with_lengths(&r1, 4.f, 5.f);
printf("rectangle r1's area is %f units square\n", shape_computeArea(&r1));
return 0;
}
Я надеюсь, что это даст вам хотя бы некоторые идеи. Для успешной и богатой объектно-ориентированной структуры на C загляните в библиотеку GObject glib .
Также обратите внимание, что здесь не моделируется явный «класс», каждый объект имеет свои собственные указатели на методы, что немного более гибко, чем вы обычно найдете в C ++. Кроме того, это стоит памяти. Вы можете уйти от этого, вставив указатели методов в class
структуру и изобрести способ для каждого экземпляра объекта ссылаться на класс.