Какие методы/стратегии люди используют для создания объектов в C (не C++)?

Проблема состоит в том, что все локальные функции связывают с той же средой и таким образом с тем же i переменная. Решение (обходное решение) состоит в том, чтобы создать отдельные среды (стековые фреймы) для каждой функции (или лямбда):

t = [ (lambda x: lambda y : x*y)(x) for x in range(5)]

>>> t[1](2)
2
>>> t[2](2)
4
7
задан Svante 10 September 2009 в 09:11
поделиться

5 ответов

Посмотрите на реализацию IJG . Они не только используют setjmp / longjmp для обработки исключений, у них есть vtables и все такое. Это хорошо написанная и достаточно маленькая библиотека, чтобы вы могли получить очень хороший пример.

0
ответ дан 6 December 2019 в 07:51
поделиться

Если вы дадите переключателям то же имя, что и свойство в вашей модели, тогда MVC автоматически установит атрибут checked для соответствующей кнопки.

Я думаю, что это зависит от наличия сильного типизированная модель.

В основном GObject предоставляет общий способ описания непрозрачных значений (целых чисел, строк) и объектов (путем ручного описания интерфейса - как структуры указателей на функции, в основном соответствующих VTable в C ++) - можно найти дополнительную информацию о структуре в его справочнике

вы часто также вручную реализуете vtables, как в «COM на простом языке C»

4
ответ дан 6 December 2019 в 07:51
поделиться

Термин «объекты» вы используете немного расплывчато, поэтому я предполагаю, что вы спрашиваете, как использовать C для достижения определенных аспектов объектно-ориентированного программирования (не стесняйтесь чтобы исправить это предположение.)

Полиморфизм метода:

Полиморфизм метода обычно эмулируется в C с использованием указателей на функции. Например, если бы у меня была структура, которую я использовал для представления image_scaler (что-то, что принимает изображение и изменяет его размер до новых размеров), я мог бы сделать что-то вроде этого:

struct image_scaler {
    //member variables
    int (*scale)(int, int, int*);
}

Затем я мог бы сделать несколько масштабаторов изображения как таковые:

struct image_scaler nn, bilinear;
nn->scale = &nearest_neighbor_scale;
bilinear->scale = &bilinear_scale;

Это позволяет мне добиться полиморфного поведения для любой функции, которая принимает image_scaler и использует его метод масштабирования, просто передавая ему другой image_scaler.

Наследование

Наследование обычно достигается как таковое:

struct base{
   int x;
   int y;
} 

struct derived{
   struct base;
   int z;
}

Теперь я ' m бесплатно использовать производные ' s дополнительные поля вместе с получением всех «унаследованных» полей базы. Кроме того, если у вас есть функция, которая принимает только структуру base. вы можете просто преобразовать указатель структуры в указатель базы структуры без каких-либо последствий

7
ответ дан 6 December 2019 в 07:51
поделиться

Я обычно делаю что-то вроде этого:

struct foo_ops {
    void (*blah)(struct foo *, ...);
    void (*plugh)(struct foo *, ...);
};
struct foo {
    struct foo_ops *ops;
    /* data fields for foo go here */
};

С этими определениями структуры , код, реализующий foo, выглядит примерно так:

static void plugh(struct foo *, ...) { ... }
static void blah(struct foo *, ...) { ... }

static struct foo_ops foo_ops = { blah, plugh };

struct foo *new_foo(...) {
   struct foo *foop = malloc(sizeof(*foop));
   foop->ops = &foo_ops;
   /* fill in rest of *foop */
   return foop;
} 

Затем в коде, который использует foo:

struct foo *foop = new_foo(...);
foop->ops->blah(foop, ...);
foop->ops->plugh(foop, ...);

Этот код можно убрать с помощью макросов или встроенных функций, чтобы он выглядел более похожим на C

foo_blah(foop, ...);
foo_plugh(foop, ...);

, хотя, если вы придерживаетесь достаточно короткое имя для поля «ops», простое написание кода, показанного изначально, не особенно многословно.

Этот метод полностью подходит для реализации относительно простых объектно-ориентированных проектов на C, но он не делает обрабатывают более сложные требования, такие как явное представление классов и наследование методов. Для них вам может понадобиться что-то вроде GObject (как упоминал EFraim), но я бы посоветовал убедиться, что вам действительно нужны дополнительные функции более сложных фреймворков.

struct foo *foop = new_foo(...);
foop->ops->blah(foop, ...);
foop->ops->plugh(foop, ...);

Этот код можно привести в порядок с помощью макросов или встроенных функций, чтобы он выглядел более похожим на C

foo_blah(foop, ...);
foo_plugh(foop, ...);

, хотя, если вы придерживаетесь достаточно короткого имени для поля «ops», простое написание кода, показанного изначально, не особенно многословен.

Этот метод полностью подходит для реализации относительно простых объектно-ориентированных проектов на C, но он не обрабатывает более сложные требования, такие как явное представление классов и наследование методов. Для них вам может понадобиться что-то вроде GObject (как упоминал EFraim), но я бы посоветовал убедиться, что вам действительно нужны дополнительные функции более сложных фреймворков.

struct foo *foop = new_foo(...);
foop->ops->blah(foop, ...);
foop->ops->plugh(foop, ...);

Этот код можно привести в порядок с помощью макросов или встроенных функций, чтобы он выглядел более похожим на C

foo_blah(foop, ...);
foo_plugh(foop, ...);

, хотя, если вы придерживаетесь достаточно короткого имени для поля «ops», простое написание кода, показанного изначально, не особенно многословен.

Этот метод полностью подходит для реализации относительно простых объектно-ориентированных проектов в C, но он не обрабатывает более сложные требования, такие как явное представление классов и наследование методов. Для них вам может понадобиться что-то вроде GObject (как упоминал EFraim), но я бы посоветовал убедиться, что вам действительно нужны дополнительные функции более сложных фреймворков.

простое написание кода, показанного изначально, не является особенно подробным.

Этот метод полностью подходит для реализации относительно простых объектно-ориентированных проектов на C, но он не обрабатывает более сложные требования, такие как явно представляющие классы и наследование методов. Для них вам может понадобиться что-то вроде GObject (как упоминал EFraim), но я бы посоветовал убедиться, что вам действительно нужны дополнительные функции более сложных фреймворков.

простое написание кода, показанного изначально, не является особенно подробным.

Этот метод полностью подходит для реализации относительно простых объектно-ориентированных проектов на C, но он не обрабатывает более сложные требования, такие как явно представляющие классы и наследование методов. Для них вам может понадобиться что-то вроде GObject (как упоминал EFraim), но я бы посоветовал убедиться, что вам действительно нужны дополнительные функции более сложных фреймворков.

9
ответ дан 6 December 2019 в 07:51
поделиться

Подобно подходу Дейла, но немного больше похоже на то, как PostgreSQL представляет узлы дерева синтаксического анализа, типы выражений и тому подобное внутри. По умолчанию используются структуры Node и Expr , аналогичные строкам

typedef struct {
    NodeTag n;
} Node;

, где NodeTag - это typedef для unsigned int, а есть заголовочный файл с кучей констант, описывающих все возможные типы узлов. Сами узлы выглядят следующим образом:

typedef struct {
    NodeTag n = FOO_NODE;
    /* other members go here */
} FooNode;

и FooNode могут быть безнаказанно преобразованы в узел из-за особенности структур C: если две структуры имеют идентичные первые члены, они могут быть преобразованы друг в друга.

Да, это означает, что FooNode может быть преобразован в BarNode , что вы, вероятно, не захотите делать. Если вам нужна правильная проверка типов во время выполнения,

0
ответ дан 6 December 2019 в 07:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: