Использование указателей на функции просто для эмуляции C ++ - подобный синтаксис просто беспорядочный, без очевидных преимуществ. У вас не будет RAII в C, независимо от того, что вы делаете, поэтому вам нужно явно вызывать конструкторы / деструкторы. Если вы делаете это, набирая obj.foo()
или obj = foo()
, то не имеете абсолютно ничего общего с ОО, это просто стиль кодирования.
Основная проблема здесь заключается в том, что ваш код не имеет надлежащего дизайна ОО, так как структура полностью открыта и не использует приватную инкапсуляцию. По той же причине, что class line { public: int x; int y; };
также не является правильным ОО - вы не получаете ОО только потому, что вы вводите sh некоторые связанные переменные в агрегатный тип независимо от языка.
"Cleanest" / " самый красивый "будет означать полную приватную инкапсуляцию. В C это может быть достигнуто с непрозрачными типами. Я предпочитаю реализовывать их, не пряча указатели за typedef, поэтому:
line.h
#include <stdio.h>
#include <stdlib.h>
typedef struct line line; // forward declaration of incomplete type
line* line_construct (int x, int y);
line. c
#include "line.h"
struct line { // actual definition of the struct, local to line.c
int x; // private variable
int y; // private variable
};
line* line_construct (int x, int y)
{
line* obj = malloc (sizeof *obj);
if(obj == NULL) { /* error handling here */ }
obj->x = x;
obj->y = y;
return obj;
}
вызывающий. c
#include "line.h"
int main(void)
{
line* x = line_construct(10, 20);
}
Здесь line
инкапсулирован на 100%, и вызывающий не может получить доступ к содержимому структуры. Поскольку я не скрываю указатели за typedef, вызывающая сторона всегда должна использовать указатели line*
и никогда не может объявить экземпляр объекта напрямую.
Если конструктор предназначен только для обнуления членов структуры, тогда ему не нужно передавать какие-либо параметры, но он может делать это внутренне.
И, очевидно, вам также нужно реализовать соответствующий деструктор с free
.
line* line_destruct(line* obj) { free(obj); return NULL; }
или около того.