Это зависит от точного «объектно-ориентированного» набора функций, который вы хотите иметь. Если вам нужны такие вещи, как перегрузка и/или виртуальные методы, вы, вероятно, должны включать указатели на функции в структурах:
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
и придумать способ для каждого экземпляра объекта ссылаться на класс.
Обязательный вопрос: вам нужно написать объектно-ориентированный код? Если вы по какой-то причине, это прекрасно, но вы будете сражаться с довольно тяжелой битвой. Вероятно, это лучше всего, если вы не пытаетесь написать объектно-ориентированный код на C. Это, безусловно, возможно - см. Отличный ответ от unwind - но это не совсем «легко», и если вы работаете с встроенной системой с ограниченной памятью, может оказаться невозможным. Возможно, я ошибаюсь, но я не пытаюсь вас отговорить, просто представляю некоторые контрапункты, которые, возможно, не были представлены. –
Строго говоря, нам это не нужно. Однако сложность системы сделала код недостижимым. Я чувствую, что лучший способ уменьшить сложность - реализовать некоторые концепции ООП. Спасибо всем, кто отвечает в течение 3 минут. Вы, ребята, сумасшедшие и быстрые! –
Это просто мое скромное мнение, но ООП не делает код мгновенно поддерживаемым. Это может упростить управление, но не обязательно более удобным для обслуживания. Вы можете иметь «пространства имен» в C (Apache Portable Runtime префикс всех символов глобальных символов с помощью apr_', а GLib префикс их «g_» для создания пространства имен) и других организационных факторов без ООП. Если вы все равно собираетесь реструктурировать приложение, я бы подумал о том, чтобы потратить некоторое время, пытаясь придумать более удобную процедурную структуру. –