Как Наследование может быть смоделировано с помощью C? [дубликат]

Это было некоторое время, когда этот вопрос был отправлен, но этому все еще не отвечают...

ответ kleolb02 является хорошим. Я попытаюсь вдаваться в большее количество подробностей.

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

Это - идея из книги Gerard Meszardos" Тестовые Шаблоны xUnit " и названо "Скромным Объектом" (p. 695): необходимо разделить код логики ядра и что-либо, что пахнет как асинхронный код друг от друга. Это закончилось бы к классу для логики ядра, которая работает синхронно .

Это помещает Вас в положение для тестирования кода логики ядра в синхронный путь. Вы имеете неограниченный контроль над синхронизацией вызовов, которые Вы делаете на логике ядра и таким образом можете сделать восстанавливаемый тесты. И это - Ваше усиление от разделения логики ядра и асинхронной логики.

Эта логика ядра должна быть перенесенной другим классом, который ответственен за получение вызовов к логике ядра асинхронно и делегаты эти вызовы к логике ядра. Производственный код только получит доступ к логике ядра через тот класс. Поскольку этот класс должен только делегировать вызовы, это - "очень немой" класс без большой логики. Таким образом, можно сохранить модульные тесты на этот asychronous рабочий класс как минимум.

Что-либо выше того (тестирование взаимодействия между классами) является тестами компонента. Также в этом случае необходимо быть в состоянии иметь неограниченный контроль над синхронизацией, если Вы придерживаетесь "Скромного Объектного" шаблона.

45
задан Agnel Kurian 6 August 2009 в 06:49
поделиться

6 ответов

Это очень просто сделать так:

struct parent {
    int  foo;
    char *bar;
};

struct child {
    struct parent base;
    int bar;
};

struct child derived;

derived.bar = 1;
derived.base.foo = 2;

Но если вы используете расширение MS (в GCC используйте флаг -fms-extensions ), вы можете использовать анонимный вложенный struct s, и он будет выглядеть намного лучше:

struct child {
    struct parent;    // anonymous nested struct
    int bar;
};

struct child derived;

derived.bar = 1;
derived.foo = 2;     // now it is flat
31
ответ дан 26 November 2019 в 21:26
поделиться

Я использовал объектную систему на C, в которой использовались методы с поздним связыванием, которые позволяли объектную ориентацию с отражением.

Вы можете прочитать об этом здесь .

2
ответ дан 26 November 2019 в 21:26
поделиться

Поскольку ранние версии C ++ были в основном препроцессорами, которые преобразовывались в C, это определенно возможно.

2
ответ дан 26 November 2019 в 21:26
поделиться

Эта ссылка может быть полезна -> ссылка

Базовый пример будет похож на следующий

 struct BaseStruct
{
  // some variable
}


struct DerivedStruct
{
  struct BaseStruct lw;
  // some more variable
};
1
ответ дан 26 November 2019 в 21:26
поделиться

Вы определенно можете написать C в (отчасти) объектно-ориентированном стиле.

Инкапсуляция может быть выполнена, сохраняя определения ваших структур в файле .c, а не в связанном заголовке. Затем внешний мир обрабатывает ваши объекты, сохраняя на них указатели, и вы предоставляете функции, принимающие такие указатели, как "методы" ваших объектов.

Поведение, подобное полиморфизму, может быть получено с помощью указателей функций, обычно сгруппированы в «операционные структуры», вроде как "таблица виртуальных методов" в ваших объектах C ++ (или как там это называется). Структура операций может также включать другие вещи, такие как константы, значение которых специфично для данного «подкласса». "Родительская" структура может содержать ссылку на данные, специфичные для операций. через общий указатель void * . Конечно, «подкласс» может повторять шаблон для нескольких уровней. наследования.

Итак, в приведенном ниже примере struct printer сродни абстрактному классу, который может быть "получен" путем заполнения структуры pr_ops , и обеспечение функции-конструктора, обертывающей pr_create () . Каждый подтип будет иметь свою собственную структуру, которая будет «привязана» в объект struct printer через общий указатель data . Это демонстрируется подтипом fileprinter . Можно представить себе графический интерфейс или принтер на основе сокетов, это будет обрабатываться независимо от остальной части кода как struct printer * ссылка.

printer.h:

struct pr_ops {
    void (*printline)(void *data, const char *line);
    void (*cleanup)(void *data);
};

struct printer *pr_create(const char *name, const struct output_ops *ops, void *data);
void pr_printline(struct printer *pr, const char *line);
void pr_delete(struct printer *pr);

printer.c:

#include "printer.h"
...

struct printer {
    char *name;
    struct pr_ops *ops;
    void *data;
}

/* constructor */
struct printer *pr_create(const char *name, const struct output_ops *ops, void *data)
{
    struct printer *p = malloc(sizeof *p);
    p->name = strdup(name);
    p->ops = ops;
    p->data = data;
}

void pr_printline(struct printer *p, const char *line)
{
    char *l = malloc(strlen(line) + strlen(p->name) + 3;
    sprintf(l, "%s: %s", p->name, line);
    p->ops->printline(p->data, l);
}

void pr_delete(struct printer *p)
{
    p->ops->cleanup(p->data);
    free(p);
}

Наконец, fileprinter.c:

struct fileprinter {
    FILE *f;
    int doflush;
};

static void filepr_printline(void *data, const char *line)
{
    struct fileprinter *fp = data;
    fprintf(fp->f, "%s\n", line);
    if(fp->doflush) fflush(fp->f);
}

struct printer *filepr_create(const char *name, FILE *f, int doflush)
{
    static const struct ops = {
        filepr_printline,
        free,
    };

    struct *fp = malloc(sizeof *fp);
    fp->f = f;
    fp->doflush = doflush;
    return pr_create(name, &ops, fp);
}
13
ответ дан 26 November 2019 в 21:26
поделиться

Это должно быть возможно, по крайней мере, до некоторой степени.

Что именно вам нужно смоделировать? Наследование данных или методов?

Edit : Вот небольшая статья, которую я нашел: http://fluff.info/blog/arch/00000162.htm

2
ответ дан 26 November 2019 в 21:26
поделиться
Другие вопросы по тегам:

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