Комментарии 35
Хотел бы, чтобы весь си++ был бы реализован как макросы над этим.
Сам стараюсь писать похожим образом.
Сам стараюсь писать похожим образом.
Вообще есть objective-c.
Вот только я еще никого не видел, кто использует возможности языка как дополнение к си (без gnustep)
Вот только я еще никого не видел, кто использует возможности языка как дополнение к си (без gnustep)
Есть один внутренний проект, давний форк tarantool:
github.com/ktopus/octopus/blob/master/include/objc.h
github.com/ktopus/octopus/blob/master/include/index.h
В принципе, впечатления от «сырого» Objective-C положительные были.
github.com/ktopus/octopus/blob/master/include/objc.h
github.com/ktopus/octopus/blob/master/include/index.h
В принципе, впечатления от «сырого» Objective-C положительные были.
Ведь именно так и было в начале. Просто язык настолько разросся, что легче и эффективнее было написать компилятор напрямую.
Я бы добавил тег ненормальное программирование, а так вполне себе нормально!
А что тут ненормального? Даже в ядре linux такое используется в драйверах ФС, например.
Ядро линукс, драйверы, даже некоторые части игр (например рендер) — это системное программирование, оно отличается от прикладного. Для прикладного программирования придуманы кучи патернов, чтобы огромная армия программистов не отстреливала себе ноги. В системном свои правила, и основное — выжать максимум. Выжимается максимум явно нарушая правила прикладного программирования. Вот для обычных программистов то что в этой статье это ненормальное программирование. Для системого программирования это нормально!
Собственно это я и хотел выразить своим предыдущим посланием.
Собственно это я и хотел выразить своим предыдущим посланием.
Я это послание понял, но разве сейчас используется C в «прикладном» программировании, где не важна скорость, тем более людьми, не знающими о возможности выстрелить во все части тела?
В исходниках Quake2 подобных виртуальных функций было полно. В общем-то в C++ обычно делается отдельно таблица функций, а в объекте хранится только указатель на таблицу для экономии памяти.
О glib и linux уже сказали.
В Go наследование тоже аналогичным образом делается.
О glib и linux уже сказали.
В Go наследование тоже аналогичным образом делается.
А всё потому, что ООП — это, прежде всего, не синтаксический сахар, а парадигма. Почти на любом языке можно писать и в объектно-ориентированном стиле, и в функциональном, и в процедурном. Неудивительно, что элементы ООП встречаются во многих крупных проектах даже на тех языках, в которых нет специальных средств для ООП.
Посмотрите glib. Вот уж где действительно ООП на C.
Вы забыли «virtual» в самом первом примере кода на C++, — все три метода класса compressor должны быть виртуальными, иначе это не будет работать как вы написали.
Хочу посоветовать книгу 21st Century C. В ней очень хорошо описываются все современные приемы.
Давным давно читал ещё Object-Oriented Programming with ANSI C
а я эти приемы изучил в книге Анализ программного кода на примере проектов Open Source
Очень советую
Очень советую
скачал — спасибо
Вот очень интересная дискуссия на тему того, почему код написанный на D может быть более эффективным чем код скомпилированный на чистом С forum.dlang.org/thread/l7tij3$v6m$1@digitalmars.com
Хабр криво парсит ссылку, так, что лучше ее копировать в адресную строку.
Хабр криво парсит ссылку, так, что лучше ее копировать в адресную строку.
Спасибо большое за статью, побольше бы таких статей!!!
1. указатели на функции можно было бы завернуть в табличку виртуальных функций, чтобы было как на си++. Либо сделать как в Go/Rust и создавать интерфейсы с указателем на данные + указателем на табличку виртуальных функций.
2. не понял зачем union в наследовании «a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls» gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html
2. не понял зачем union в наследовании «a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls» gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html
Union затем, чтобы можно было обращаться к базовому объекту по имени для передачи в код, ожидающий объект базового типа, т.е. для полиморфного использования в существующем коде и также чтобы возможно использовать данные базового объекта напрямую. В статье об этом есть.
>Union затем, чтобы можно было обращаться к базовому объекту по имени для передачи в код, ожидающий объект базового типа
«a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls»
там даже пример есть в документации.
«a pointer to a structure is automatically converted to a pointer to an anonymous field for assignments and function calls»
там даже пример есть в документации.
Порекомендую воздерживаться от макросов, которые неявно объявляют переменные в коде. Лучше воспользоваться например такой формой:
#define PREPARE_IMPL© \
({ \
assert©; \
assert(c->impl_); \
(rar_impl_t*)c->impl_; \
})
…
rar_impl_t *impl = PREPARE_IMPL©;
#define PREPARE_IMPL© \
({ \
assert©; \
assert(c->impl_); \
(rar_impl_t*)c->impl_; \
})
…
rar_impl_t *impl = PREPARE_IMPL©;
Список «что я хочу от Си» можно дополнить возможностью перегружать обычные функции. В Си этого нет, к сожалению. Нельзя давать функциям одинаковые имена. Код
не компилируется компиляторами чистого Си, например TinyCC. Можно писать без классов и шаблонов и думать, что они пишешь на чистом Си. И компиляторы C++ поддерживают в этом заблуждении. Когда же берёшь шустрый в компиляции TinyCC, то тут открываются глаза.
Из компиляторов Си вроде бы только LCC поддерживает перегрузку функций. Но это расширение, не соответствующее стандарту.
int add2(int ar) { return ar+2;};
float add2(float ar) { return ar+2.0;};
не компилируется компиляторами чистого Си, например TinyCC. Можно писать без классов и шаблонов и думать, что они пишешь на чистом Си. И компиляторы C++ поддерживают в этом заблуждении. Когда же берёшь шустрый в компиляции TinyCC, то тут открываются глаза.
Из компиляторов Си вроде бы только LCC поддерживает перегрузку функций. Но это расширение, не соответствующее стандарту.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Object oriented C