Можно ли эмулировать методы объекта в 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# для объектно-ориентированного программирования, но иногда приходится обходиться.

Другие вопросы по тегам