Можно ли эмулировать методы объекта в C?
Можно ли эмулировать методы объекта в C? Я хотел бы иметь возможность самостоятельно ссылаться на структуру в качестве параметра аргумента функции-члена, например:
struct foo {
int a;
int (*save)(struct foo *);
};
int
save_foo(struct foo *bar) {
// do stuff.
}
struct foo *
create_foo() {
struct foo *bar = malloc(sizeof(struct foo));
bar->save = save_foo;
return bar;
}
int
main() {
struct foo *bar = create_foo();
bar->a = 10;
bar->save();
}
Куда, bar->save()
на самом деле звонки save_foo(bar)
, Похоже на длинный выстрел, но это было бы довольно гладко:)
5 ответов
Нет, это невозможно. В C есть объектно-ориентированные библиотеки, но они проходят "this
"объект к" методу "явно как в
bar->save(bar);
Посмотрите API-интерфейс Berkeley DB C для примера этого стиля, но подумайте об использовании C++ или Objective-C, если вы хотите сделать OO на C-подобном языке.
В основном нет. Ссылка на функцию в C - это просто указатель на то, где она находится, и когда вы вызываете ее, вы просто берете указатель из структуры, переходите туда и продолжаете выполнение без каких-либо знаний о контексте или стеке, так что есть некуда взять "это".
Да пройти bar
к save
указатель на функцию, и вы получите то, что C++ делает изнутри (незаметно проходит this
в качестве первого параметра метода). Вы не можете получить this
(ака bar
) автоматически передается в C.
Ответ: "Да".
Доказательство тому, что первые компиляторы C++ вообще не были компиляторами. Они просто перевели код C++ в код C. Компилятор CFront сделал это.
Из других ответов я вижу, что я, вероятно, неправильно понял ваш вопрос. Нет, синтаксис, который вы написали в вопросе, не будет работать в C. Вам нужно написать свой собственный тип препроцессора / транслятора для преобразования вызова из bar->save()
в foo_save(bar)
или даже C3fooF4save(bar)
,
Да просто неловко. Я реализовал объекты в Fortran77, используя именованные общие блоки.
В C, вероятно, лучше всего использовать структуры. Если вы не хотите передавать структуры, вы можете сделать их глобальными и получить к ним доступ таким образом. Какой бы обходной путь вы ни выбрали, хорошо его прокомментируйте!
Иногда приходится использовать C, а C++, Objective C и т.д. недоступны. Мне нравятся Java и C# для объектно-ориентированного программирования, но иногда приходится обходиться.