Как стать автором
Обновить

Комментарии 54

Реализация инструментов ООП в языках, для этого не предназначенных (привет Fortran'у) — это конечно полезно с точки зрения образования.
А что насчет практической пользы?
В общем-то, ООП на C не новость. Ярчайший пример — GTK+. И в нем используются виртуальные функции (хотя, несколько по-другому).
о GTK+ не знал, спасибо! Интересно, чем их не устроило ООП в C++?
(Вики говорит в пользу C только про «желание легко строить интерфейсы для других языков программирования»)
Это им ненависть Торвальдса к C++ передалась, судя по всему :)
НЛО прилетело и опубликовало эту надпись здесь
ИМХО его следовало бы включить в стандарт С++11
Objective C туда же. Там, кстати, все функции являются виртуальными.
Ну, Objective C — полноценный язык. А GTK+ — просто библиотека, без всяких расширений.
в ObjC виртуальные функции обрабатываются компилятором и рантаймом, разработчику не нужно заполнять руками какие-то странные структуры, как в примере из топика
А вы знаете чем за такие соменительные преимущества приходится платить? Рантайм связывание всегда и везде ведет к нехилой потере скорости, кроме того для универсальности (Я полагаю именно так) введено общение с обьектом только через укащатель, а сам обьект создается динамически. За год работы с этой дрянью я понял только одно — этот язык хорошо решает те проблемы которые в других языках програмирования не встречаются.
Самая соль ООП для С реализована в библиотеке Glib, которую GTK просто использует.
А что такое «язык, не предназначенный для ООП», позвольте узнать?
В ООП-стиле можно писать на любом языке.
Очевидно это язык, не имеющий встроенных синтаксических средств для ООП.
Про то, что писать можно на любом, это конечно да. Даже на Brainfuck, полагаю :)
Ну по этой логике, Сысоеву ни в коем случае не следовало бы писать nginx на Си. Ведь немало языков предоставляют возможности для организации параллельных легковесных задач и их координации. А в Си ничего подобного нет, следовательно он не предназначен для данной задачи.
Видимо, необходимо доступнее изложить мою мысль.

Так вот, при выборе языка под задачу, учитывается разное. Производительность, скорость разработки, наличие библиотек и так далее. Могут быть какие-то специфические требования.

Наличие поддержки ООП в языке — безусловно плюс, по шкале «скорость разработки». Но если есть другие критерии, помимо скорости разработки, тогда внезапно может выиграть язык без встроенной поддержки ООП.

Еще раз — в ООП стиле можно писать на любом языке. Есть языки в большей или меньшей степени приспособленные к этому. Совсем непригодных нет.
Согласен, что слово не предназначен не совсем верно передает идею моего высказывания. Я недоумевал именно об ООП в C, в то время как уже существует, на мой взгляд, общепризнанный и успешный его наследник с имплементацией ООП — C++
Что касается вашего примера, то настоящий профессионал вполне может рассчитывать на то, что способен реализовать, например, «организацию параллельных легковесных задач и их координации» лучше, чем в существующих на данный момент решениях, и избрать как раз подходящий для таких фундаментальных задач чистый Си. Возможно, и создание GTK+ объясняется именно этим.
ядро Линукса передаёт вам привет
НЛО прилетело и опубликовало эту надпись здесь
А что мешает использовать в ядре С++ и виртуальные функции?
Ну, а кроме предрассудков что-то мешает?
Квинтэссенция отношения Линуса к C++ заключена в первой же строчке письма. Он, видимо, не осилил ООП («idiotic «object model» crap»). Ну и производительность его не устраивает, якобы.
Вот тут краткое обсуждение проблем использованием C++ в ядре (via Microsoft).

В ядре макоси С++ ограниченно применяется, но например иксепшены находятся под запретом.
НЛО прилетело и опубликовало эту надпись здесь
exceptions и RTTI можно не использовать.
Бардак в ABI нас не волнует, если мы наружу не будем выставлять плюсовые интерфейсы.
Чем мешает недетерминированность вызова конструкторов глобальных объектов? Если нужно, чтобы было детерминированно — можно обойтись без глобальных объектов в конце концов.

Ну и вот объясните, зачем выдумывать виртуальные функции на С, когда можно было взять С++, отказаться от всего вышеперечисленного, но пользоваться виртуальными функциями по-человечески?
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
>И что получим в результате? Убожество под названием С с классами.

… которое при этом всё равно будет куда элегантнее для поставленной в топике задачи, чем ванильный C99.
Зачем запрещать STL, наследование, перегрузку и шаблоны? Если с RTTI и исключениями есть реальные проблемы то с остальным то что не так? И даже если отказаться от всего остального все равно останется полноценный ООП-язык.
Ну RTTI и ABI — это понятно в чем проблема, но с exceptions то что такого?
НЛО прилетело и опубликовало эту надпись здесь
Суть виртуальных функций не в том, что их можно переопределить, а в том, что они всегда вызываются от действительного инстанса класса.

ClassA *instance = new ClassB();
std::cout << instance->get() << std::endl; // выведет 9, а без модификатора virtual было бы 11
Суть примера в начале статьи не в вызове метода get(), а в вызове соответствующего метода set() в теле метода get().
Хотя трактовка виртуальной функции в статье, действительно, немного странная.
Мда, пример можно было сделать и попроще — я его даже не понял с первого раза.
Я сам сразу ему удивился и хотел написать гневный комментарий, но повременил и разобрался.
Да, тоже немного удивился отсутствию слова «полиморфизм» в статье про виртуальные функции.
Автор статьи порадовался переводу: twitter.com/#!/milot/status/172245024837349378 :)
НЛО прилетело и опубликовало эту надпись здесь
«В C не существует указателя this, который указывал бы на вызывающий объект. Я назвал параметр та́к, для того чтобы сымитировать использование указателя this в C++»

Отличное решение — если теперь файл когда-либо потребуется скомпилировать С++ компилятором, нас ждет облом из-за ключевого слова this. Что не так уж и невероятно — представьте себе, что этот код попал в хидер Си-шной библиотеки, которую нужно использовать из C++.
Это пример, который показывает сходства и различие ключевых моментов, ежу понятно, что когда это будет в продакшн библиотеке (неважно зачем бы оно вообще потребовалось), никто не будет писать this.
В Quake 3 у ID Software как раз меню подобным извращение было реализовано. Была структура с указателями на функции и они разные функции присваивали в инициализацие меню.
НЛО прилетело и опубликовало эту надпись здесь
Люблю С за то, что на нём можно сделать виртуальный конструктор, события и св-ва, в отличие от С++.
Хотите сказать, то же самое никак не сделать в C++?.. Нужен «виртуальный конструктор» — есть всяческие фабрики. События и свойства вполне успешно реализованы в Qt
Про фабрики не знаю, а Qt не С, да и не устраивают меня их св-ва и события.
не устраивает != невозможно
Несколько дополнений. В vtable конструктор не нужен, т.к. виртуальных конструкторов — не бывает, и компилятор знает какой именно вызывать на этапе компиляции. Пример можно было бы дополнить, как раз виртуальным деструктором.
Также на практике наследование представлено в виде дублирования полей, а не как поле типа базового класса. Для примера вспомните виртуальное наследование.
В дополненение ваш пример можно было расширить созданием/уничтожением глобальных объектов, и использованием new/delete.
Сам написал подобную статью несколько месяцев назад, но отверстать так руки не дошли. Там также описано про RTTI, и исключения средствами С.
Это перевод. Можете оставить этот комментарий у автора в блоге по ссылке.
Виртуальные конструкторы бывают, только не на C++.
Лучше бы их не было…
За что вы их так?
Ну да, усложнение синтаксиса.
Но проблема-то в чем?
На нечто такое я натыкался в библиотеке ffmpeg, которая при ближайшем расмотрении оказалась написаной в основном на чистом Си.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории