Ваш код может дать сбой, если нет ввода.
Используйте стандартную функцию strstr()
. Зачем изобретать велосипед? Вы также можете улучшить сложность кода. Смотрите эту ссылку:
Первый компилятор C++ ("C с классами") на самом деле сгенерировал бы код C, таким образом, это определенно выполнимо.
В основном, Ваш базовый класс является структурой; полученные структуры должны включать основную структуру в первое положение, так, чтобы указатель на "полученную" структуру также был допустимым указателем на основную структуру.
typedef struct {
data member_x;
} base;
typedef struct {
struct base;
data member_y;
} derived;
void function_on_base(struct base * a); // here I can pass both pointers to derived and to base
void function_on_derived(struct derived * b); // here I must pass a pointer to the derived class
функции могут быть частью структуры как указатели функции, так, чтобы синтаксис как p-> вызов (p) стал возможным, но все еще необходимо явно передать указатель на структуру к самой функции.
Общий подход должен определить структуру с указателями на функции. Это определяет 'методы', которые можно назвать на любом типе. Подтипы затем устанавливают свои собственные функции в этой общей структуре и возвращают ее.
, Например, в ядре Linux, существует структура:
struct inode_operations {
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *,
struct nameidata *);
...
};
Каждый зарегистрированный тип файловой системы затем регистрирует свои собственные функции для create
, lookup
, и остающиеся функции. Отдых кода может, чем использование универсальный inode_operations:
struct inode_operations *i_op;
i_op -> create(...);
C++ не это далеко от C.
Классы являются структурами со скрытым указателем на таблицу указателей функции под названием VTable. Сам Vtable статичен. Когда типы указывают на Vtables с той же структурой, но где указатели указывают на другую реализацию, Вы получаете полиморфизм.
рекомендуется инкапсулировать логику вызовов в функции, которые берут структуру в качестве параметра для предотвращения помехи кода.
Вы должны также encapsulcte инстанцирование структур и инициализация в функциях (это эквивалентно конструктору C++), и удаление (деструктор в C++). Это хорошая практика так или иначе.
typedef struct
{
int (*SomeFunction)(TheClass* this, int i);
void (*OtherFunction)(TheClass* this, char* c);
} VTable;
typedef struct
{
VTable* pVTable;
int member;
} TheClass;
Для вызова метода:
int CallSomeFunction(TheClass* this, int i)
{
(this->pVTable->SomeFunction)(this, i);
}
Приложение B статьи Открывает Reusable Object Models Ian Piumarta и Alessandro Warth , VPRI является реализацией Объектной модели в GNU C, приблизительно 140 строках кода. Это - захватывающее чтение!
Вот некэшируемая версия макроса, который отправляет сообщения в объекты, с помощью расширения GNU C ( выражение оператора):
struct object;
typedef struct object *oop;
typedef oop *(*method_t)(oop receiver, ...);
//...
#define send(RCV, MSG, ARGS...) ({ \
oop r = (oop)(RCV); \
method_t method = _bind(r, (MSG)); \
method(r, ##ARGS); \
})
В том же документе, взгляните на object
, vtable
, vtable_delegated
и symbol
структуры, и _bind
и vtable_lookup
функции.
За Ваше здоровье!
Функции файла fopen, fclose, освобожденный являются примерами кода OO в C. Вместо частных данных в классе они работают над Файловой структурой, которая используется для инкапсуляции данных, и действия функций C как членский класс функционирует. http://www.amazon.com/File-Structures-Object-Oriented-Approach-C/dp/0201874016