Я, вероятно, не может в полной мере следить за ходом дискуссии из-за языкового барьера, но у меня есть трудное время, чтобы понять, почему есть споры.
Принципы ООП существовали задолго до термин ООП был популярным. C + + сам начал в качестве предварительного процессора, что выход чистого C код, который затем был составлен компилятором C. Инкапсуляции данных, наследование, полиморфизм были все переведены на C кода.
Метод связывания, что Олег описывает, с участием имя-коверкая и вырезания объектов в 500 000 штук не был изобретен Олег - это была вокруг в течение десятилетий, и точно, как C + + компиляторов работы. Разница лишь в том вы не видите все эти файлы, как разрезы компилятора вещи и ставит его в один файл объекта. Предварительно скомпилированные заголовки и постепенно компиляции в объектные файлы являются как этот процесс ускорился.
Другой aternative помощью # IFDEF * не * эквивалентны и используется только когда инструменты, чтобы сделать это автоматически не доступны.
Примеры методов ООП, я могу предложить некоторые в z88dk реализованного в z80 ассемблере. Я не вижу никакой разницы между С и z80 ассемблере поэтому они должны служить в качестве заменителя.
У нас есть несколько контейнеров в z88dk по образцу C + + STL. Все это реализовать [B] Отношения наследования [/ B]. Один простой пример: "массива байтов" является одним из основных тип, который может хранить фиксированный размер массива байтов. Он определяет операции для добавления, индекс, скопируйте строки в / из и т.д. "байт Vector" наследует от "массива байтов". Все "массив байт" функции можно также назвать на "байт Вектор». Но "Байт Вектор" добавляет операций, которые позволяют основной массив для выращивания или сократилась с помощью Realloc (). Это наследство вместе с увеличением подкласса. Это очень легко сделать в C или ассемблере, устраивая иметь данные в "базового класса" появляются в начале структуры "подкласса".
[B] инкапсуляции данных [/ B], еще один принцип ООП. Конечно, инкапсуляции данных существует уже с начала вычислений. Под С его называют "абстрактные типы данных" и легко реализуется с помощью структуры для хранения личных данных и публичный интерфейс, доступный как документально функции, принимающие указатели на структуры в качестве параметра. В z88dk, одним из примеров является библиотека SP1 спрайт.
Полиморфизм. Это один видно реже. В z88dk мы используем полиморфизм в STDIO. Файл (данные) + его водитель (методы) представляют собой полиморфный объект. Вид полиморфизма мы используем это как то, что находится в Smalltalk и Java. Как Smalltalk, это делается через передачи сообщений и, как Java, мы указываем интерфейсы, что водители должны быть реализованы.
Интерфейс STDIO содержит сообщения типа "putc", "читать", "писать" и т.д. Все Printf / зсапЕ / поиск / и т.д. операции переводятся в небольшом количестве сообщений, каждый из которых идентифицируется байта. Файловая структура, что эти сообщения отправляются содержит z80 JP инструкцию для водителя. Водитель декодирует сообщение с помощью переключателя о "CP STDIO_MSG_READ", и переходит к правильному действию.
В дополнение к STDIO интерфейс, есть консольный интерфейс для текста ввода / вывода на экран, интерфейс символов для таких вещей, как последовательных устройств, а также интерфейс диска для дисковых устройств. Эти интерфейсы реализованы все таким же образом с использованием сообщений.
Мы также почти сделать обобщенное программирование как несколько библиотек используют понятие итераторов. Библиотека спрайт SP1 имеет несколько функций итераторов пройти списки символов квадратов обновить на экране, списки экраном плитки, списки спрайтов но эти списки одного типа объекта. В С (или ASM) это очень легко сделать их списки любого вида объект, реализующий определенный интерфейс. Все что нужно, это каждая структура в списке нуждается указатель на функцию, функции, реализующей операцию. Поскольку указатель функции является членом структуры, каждый элемент в списке может быть другой объект, и вот еще один пример как обобщенное программирование и полиморфизм.
Чем сильнее тип полиморфизма реализовать то, что сделано с виртуальными функциями, так что это видели реже. Но это может быть сделано путем иметь массивы указателей на функции, которые реализуют методы каждой части объекта.
Все эти вещи были сделаны в С, так как его ранней истории. C + + просто обеспечивает поддержку компилятора просто реализовать эти функции, что означает меньше ошибок и более сложные программы.
===
I probably can't fully follow the discussion because of the language barrier, but I have a hard time to understand why there is controversy.
OOP principles existed long before the OOP term was popularized. C++ itself started as a pre-processor that output pure C code that was then compiled by a C compiler. Data encapsulation, inheritance, polymorphism were all translated to C code.
The linking method that Oleg describes, involving name-mangling and cutting objects into 500,000 pieces was not invented by Oleg -- this has been around for decades and is exactly how C++ compilers work. The only difference is you don't see all those files as the compiler cuts stuff up and puts it into a single object file. Pre-compiled headers and incrementally compiling into object files are how this process is sped up.
The other aternative using #ifdef is *not* equivalent and is only used when the tools to do this automatically are not available.
For examples of OOP techniques, I can offer some in z88dk implemented in z80 assembler. I don't see any difference between C and z80 assembler so they should serve to act as substitute.
We have several containers in z88dk modelled on C++ STL. These all implement inheritance relationships. One easy example: "Byte Array" is a fundamental type that can store a fixed size array of bytes. It defines operations to append, index, copy strings to / from, etc. "Byte Vector" inherits from "Byte Array". All "Byte Array" functions can also be called on a "Byte Vector". But "Byte Vector" adds operations that allow the underlying array to be grown or shrunk via realloc(). This is inheritance along with augmentation of the subclass. It's very easy to do in C or asm by arranging to have the "base class's" data appear at the beginning of the "subclass's" structure.
Data encapsulation is another OOP principle. Of course, data encapsulation has been around since the beginning of computing. Under C it is called "Abstract Data Types" and is easily implemented using structures to hold private data and a public interface available as documented functions taking pointers to the structure as parameter. In z88dk, one example is the sp1 sprite library.
Polymorphism. This one is seen less often. In z88dk we use polymorphism in stdio. A FILE (data) + its driver (methods) constitute a polymorphic object. The kind of polymorphism we use is like what is found in smalltalk and Java. Like smalltalk, it's done through message passing and like Java, we specify interfaces that the drivers must implement.
The stdio interface contains messages like "putc", "read", "write", etc. All printf/scanf/seek/etc operations are translated into a small number of messages, each one identified by a byte. The FILE structure that these messages are sent to contains a z80 JP instruction to the driver. The driver decodes the message using a switch statement "CP STDIO_MSG_READ", and jumps to the correct action.
In addition to the stdio interface, there is a console interface for text i/o to the screen, a character interface for things like serial devices, and a disk interface for disk devices. These interfaces are all implemented in the same way using messages.
We also almost do generic programming as several libraries use the concept of iterators. The sp1 sprite library has several iterator functions to traverse lists of character squares to update on screen, lists of screen tiles, lists of sprites but these are lists of one type of object. In C (or asm) it is really easy to make them lists of any kind of object implementing a specific interface. All that is needed is each structure in the list needs a function pointer to a function implementing the operation. Because the function pointer is a member of the structure, each item in the list can be a different object and here is another example of both generic programming and polymorphism.
The harder type of polymorphism to implement is that done with virtual functions, so it's seen less often. But this can be done by having arrays of function pointers that implement the methods of each part of the object.
All these things have been done in C since its early history. C++ just provides compiler support to simply implement these features which means fewer errors and more complex programs.

