Форум программистов, компьютерный форум CyberForum.ru

Инкапсуляция, иттераторы, абстрактные списки на С - C++

Восстановить пароль Регистрация
 
Selina
122 / 0 / 0
Регистрация: 10.10.2009
Сообщений: 23
24.09.2010, 13:08     Инкапсуляция, иттераторы, абстрактные списки на С #1
Сразу подчеркиваю, что реализовать программу надо на С, а не на С++, что, собственно и портит всю малину.

Задание следующие: существуют некоторые "животные", которые инициализирующий в программе единым методом, потом абстрактный список животных передается другому методу, который при помощи итератора этих животных "кормит", ну, по какому-то там параметру.

Будь это С++, тут никаких проблем в реализации при помощи STL, а вот какие библиотеки и типы юзать в обычном С, ума не приложу 0_о
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.09.2010, 13:08     Инкапсуляция, иттераторы, абстрактные списки на С
Посмотрите здесь:

Иттераторы C++
Инкапсуляция. C++
C++ Инкапсуляция в ООП и C++
C++ инкапсуляция
C++ Иттераторы
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
24.09.2010, 18:04     Инкапсуляция, иттераторы, абстрактные списки на С #2
В составе языка Си нет ни того, ни другого, ни третьего. Следовательно, придётся воспроизводить такие вещи вручную. Абстракция типов данных достигается за счёт использования типа void*, итераторы - указатели или структуры, инкапсуляция данных при помощи структур, инкапсуляция методов имитируется явной передачей this.
Selina
122 / 0 / 0
Регистрация: 10.10.2009
Сообщений: 23
24.09.2010, 18:55  [ТС]     Инкапсуляция, иттераторы, абстрактные списки на С #3
Nick Alte, спасибо!
В результате решила сделать следующим способом:
1. создаем структуру list:
C
1
2
3
4
5
struct list{
    void *pointer;
    list *prev;
    list *next;
};
2. уже на нее вешаем инициализированные структуры животных;
3. Итератор представляет собой функцию, входными параметрами которой является указатель *list. После отработки функция вернет или адрес, или 0.
4. Функция кормления, ей передается целое число и в зависимости от него она вызывает различные итераторы, и, следовательно, по-разному кормятся животные.
Selina
122 / 0 / 0
Регистрация: 10.10.2009
Сообщений: 23
27.09.2010, 00:06  [ТС]     Инкапсуляция, иттераторы, абстрактные списки на С #4
Эх, меня завернули.
Предложила следующее решение:
Задание: есть структуры разных "животных", создается функция-инициализатор этих объектов. Формируется абстрактный список этих животных и пользуясь этим списком, надо животных "покормить", при помощи итератора.

В данной задаче предполагается реализация циклического списка.
Глобальные переменные программы:
head - указатель на начало списка;
n - число элементов.

Абстрактный список сформируем при помощи следующей структуры:
struct list{
void *pointer;
int code;
list *prev;
list *next;
};

prev, next - указатели на последующий и предыдущий элемент списка;
pointer - указатель на "животное";
code - "код" животного, иначе не будет возможности "разыменовывать" pointer.

Предположим, что у всех животных есть следующие параметры: имя, вес, уровень настроения.
Тогда, возможно создать функции-итераторы: по критериям имени, веса и настроения.
В качестве входных параметров будет использоваться ссылка на элемент списка. Возвращать функция будет ссылку на последующий элемент.
Если функции передать во входных параметрах 0, то она начнет поиск с "головы" списка.
Если функция не нашла последующего элемента в списке, она вернет 0.
В начале работы итератора по адресу из поля pointer извлекается объект.

Далее описывается функция "кормления" животных, входными параметрами которой является некоторое число, в зависимости от которого будет вызываться итератор.
На что получила ответ:
Разыменовывать животных - не круто, можно все инкапсулировать при помощи указателей на функции. Если ты получше подумаешь, то обойдешься одной абстрактной структурой и несколькими конкретными для каждого типа животного. Все животные должны иметь разные параметры. И не обязательно все животные должны обрабатываться всеми итераторами. Если параметра вдруг нет, то итератор пропускает этот элемент списка. Твоя задача на "С" изобразить наследование из "С++", а не написать программу на структурном языке.
Как выкидывать не нужные элементы в итераторе и изобразить наследование с помощью структур, я представляю.
А вот обойтись без разыменовывания, а заменить это указателем на функции, я не представляю.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
27.09.2010, 19:25     Инкапсуляция, иттераторы, абстрактные списки на С #5
Не совсем ясно, чего такого странного хочется автору задания. Ему нужно имитировать наследование? Ну что же, можно и поимитировать всурьёз и правильно - с таблицами виртуальных функций, преобразованиями адресов и прочей радостью - и это только из минимально необходимой части для одиночного наследования... А ведь есть ещё и множественное, да ещё и виртуальное наследование, это вообще особая радость.
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
28.09.2010, 03:07     Инкапсуляция, иттераторы, абстрактные списки на С #6
Цитата Сообщение от Selina Посмотреть сообщение
А вот обойтись без разыменовывания, а заменить это указателем на функции, я не представляю.
Эмулировать полиморфизм с таблицей виртуальных функций. Делается все это долго и нудно. Посмотри на вот этот пример:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h>
#include <stdlib.h>
 
// forward declaring the animal class
struct animal;
typedef struct animal animal;
 
// animal virtual table
typedef struct
{
    int  (*energy_level) (animal * self);
    void (*feed)         (animal * self, int food);
    void (*run)          (animal * self, int time);
    void (*delete)       (animal * self);
} animal_vtbl;
 
// animal class, abstract
struct animal
{
    animal_vtbl * vtbl;
};
 
// animal method dispatchers
int energy_level(animal * self)
{
    return self->vtbl->energy_level(self);
}
 
void feed(animal * self, int food)
{
    self->vtbl->feed(self, food);
}
 
void run(animal * self, int time)
{
    self->vtbl->run(self, time);
}
 
void delete(animal * self)
{
    self->vtbl->delete(self);
}
 
// lion class, derives from animal
typedef struct 
{
    animal  base;
    int     energy;
} lion;
 
// lion virtual method overrides
int lion_energy_level(lion * self)
{
    return self->energy;
}
 
void lion_feed(lion * self, int food)
{
    if (self->energy >= 0)
        self->energy += food;
}
 
void lion_run(lion * self, int time)
{
    self->energy -= time;
    if (self->energy < 0)
        self->energy = -1;
}
 
void lion_delete(lion * self)
{
    free(self);
}
 
// lion virtual table
static animal_vtbl lion_vtbl =
{
    lion_energy_level
  , lion_feed
  , lion_run
  , lion_delete
};
 
// lion constructor
animal * lion_create(int energy)
{
    lion * l = calloc(1, sizeof(lion));
    l->base.vtbl = &lion_vtbl;
    l->energy = energy;
    return &l->base;
}
 
int main()
{
    animal * a = lion_create(10);
    printf("initial lion's energy: %d\n", energy_level(a));
    run(a, 5);
    printf("lion's energy after running for %d hours: %d\n", 5, energy_level(a));
    feed(a, 2);
    printf("lion's energy after feeding: %d\n", energy_level(a));
    delete(a);
    return 0;
}
Selina
122 / 0 / 0
Регистрация: 10.10.2009
Сообщений: 23
28.09.2010, 16:19  [ТС]     Инкапсуляция, иттераторы, абстрактные списки на С #7
alexzak, спасибо!
Вопрос только в следующем, в виртуальной таблице лежат ссылки на функции, а вот к примеру в:
C
1
2
3
4
void feed(animal * self, int food)
{
    self->vtbl->feed(self, food);
}
Это как бы уже самому надо feed(self, food) дописывать?

Добавлено через 1 час 22 минуты
А, все, поняла)
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
28.09.2010, 17:52     Инкапсуляция, иттераторы, абстрактные списки на С #8
Цитата Сообщение от Selina Посмотреть сообщение
А, все, поняла)
Молодец
Selina
122 / 0 / 0
Регистрация: 10.10.2009
Сообщений: 23
28.09.2010, 19:01  [ТС]     Инкапсуляция, иттераторы, абстрактные списки на С #9
Вот только проблема в том, что:
C
1
2
3
4
int lion_energy_level(lion * self)
{
    return self->energy;
}
он не съедает как параметр своей виртуальной таблицы, потому что у нее входной параметр (lion *self), a идейно должен быть (animal *self).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.09.2010, 19:55     Инкапсуляция, иттераторы, абстрактные списки на С
Еще ссылки по теме:

C++ wxDev-C++ и инкапсуляция
C++ Инкапсуляция. классы
C++ Наследование и инкапсуляция в C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
28.09.2010, 19:55     Инкапсуляция, иттераторы, абстрактные списки на С #10
Цитата Сообщение от Selina Посмотреть сообщение
он не съедает как параметр своей виртуальной таблицы, потому что у нее входной параметр (lion *self), a идейно должен быть (animal *self).
Съедает с предупреждением, если компилировать как C. Но можно переписать и так:
C
1
2
3
4
5
int lion_energy_level(animal * self)
{
    lion * this = (lion *) self;
    return this->energy;
}
Yandex
Объявления
28.09.2010, 19:55     Инкапсуляция, иттераторы, абстрактные списки на С
Ответ Создать тему
Опции темы

Текущее время: 00:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru