Quantcast
Channel: Linux.org.ru: Форум (тех. форум)
Viewing all articles
Browse latest Browse all 74681

c-oop-gen: ООП в Си

$
0
0

Программирование в ООП-стиле на Си как правило порождает достаточно большое количество boiler plate кода. А итоговая программа пестрит приведениям типов. «Хватит это терпеть» решил я и запилил сие поделие: https://github.com/KivApple/c-oop-gen.

1) Вы описываете структуру классов (поля, методы, наследование) в XML-формате.

2) Вы генерируете два заголовочных файла из этого описания. Рекомендуется делать это не в ручную, а в качестве одного из шагов компиляции проекта.

3) Первый файл вы инклюдите всюду, где хотите использовать описанные классы. Второй файл вы инклюдите только в модуль с реализацией соответствующих классов (там описаны таблицы виртуальных методов).

4) PROFIT

Пример описания пакета классов:

<?xml version="1.0" encoding="utf-8" ?>
<package>
    <include file="stdlib.h"/>
    <class name="BaseObject">
        <method name="destroy" virtual="yes">
        </method>
    </class>
    <class name="DerivedObject" inherits="BaseObject">
        <field name="tmp" type="int"/>
        <method name="foo">
            <arg name="bar" type="int"/>
        </method>
        <method name="staticMethod" static="yes"/>
    </class>
</package>

После этого методы классов можно вызывать легко и просто:

DerivedObject_foo(another_object, 10);
DerivedObject_staticMethod();
DerivedObject_destory(another_object);
BaseObject_destroy(some_object);

Как можно заметить, при наследовании класса от другого, создаются обёртки для всех методов, которые не были переопределены, что позволяет отказаться от ручного приведения типов.

Поддерживаются виртуальные методы (как абстрактные, так и имеющие реализацию, к слову, переопределять в потомках можно только виртуальные методы), статические методы (не наследуются потомком, рекомендуется конструкторы делать на них) и обычные. Также любые методы могут получить переменное число аргументов с помощью атрибута «variadic».

Конструктор может быть любой функцией. Главное присвоить obj->vtable = &ClassName_vtable, если класс содержит хотя бы один виртуальный метод.

Деструкторы - это обычные виртуальные функции.

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

В отличии от многих других библиотек привносящих ООП в Си, сгенерированный код не требует НИЧЕГО (даже libc). Ведь это просто набор define'ов и структур.

Кстати, пакеты классов могут использовать друг-друга с помощью <include package=«some-package.xml»>. В этом случае можно будет наследоваться от классов объявленных в другом пакете (а сгенерированный исходник будет содержать #include «some-package.h»). При этом однако же генерировать заголовочный файл для подключенного пакета придётся отдельно.

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

В общем, такие дела. Покритикуйте какие ещё возможности стоит добавить, а что, возможно, я сделал не так. Сообщения о багах также приветствуются. Безусловно, данный проект можно написать достаточно быстро, но я не нашёл аналогичные проекты.

 , , , ,


Viewing all articles
Browse latest Browse all 74681

Latest Images

Trending Articles