LINUX.ORG.RU

Классы

 , ,


1

2

Зачем нужны классы?

Глянул я исходники flare. Везде одни классы, да классы. Вот у меня в рогалике на данный момент нет ни одно класса. Везде обхожусь методами.

Может я чего то не понимаю? Зачем они нужны, если всегда вместо них можно обойтись методами? Да и в си их нету.

Ответ на: комментарий от unsigned

Только ценой потерь в скорости и/или уймы рутинного кода. И не всё можно сделать, что есть в C++.

потерь в скорости

Скорости разработки, может быть, но не скорости выполнения.

уймы рутинного кода

По сути, если указанные механизмы нужны редко, то и кода получается не так уж и много.

Только простейшие случаи.

Не спорю, тем более что define-ы - тоже зло...

backbone ★★★★★
()
Ответ на: комментарий от backbone

но не скорости выполнения

Инкапсуляции на уровне C++-ного private можно добиться только убрав член класса из хедера, и тогда прямой доступ к нему пропадает.

А если городить полноценное ООП, то некоторые вещи придётся делать в рантайме (в C++ они возможны во время компиляции).

если указанные механизмы нужны редко, то и кода получается не так уж и много

У тебя в main.c, например, много ручного приведения типов. А это не только хуже читается, но и опасно.

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Инкапсуляции на уровне C++-ного private можно добиться только убрав член класса из хедера, и тогда прямой доступ к нему пропадает.

Так и есть. Реализуется модулями, как отметили выше.

А если городить полноценное ООП, то некоторые вещи придётся делать в рантайме (в C++ они возможны во время компиляции).

Цели городить ООП не ставилось. Можно придерживаться функционального подхода и там, где требуется какой-то механизм, например, полиморфизм, реализовать виртуальные методы. Интерфейс остаётся функциональным, реализуется через inline-врапперы. Никаких потерь по сравнению с C++ нет; как и в C++ в объекте хранится указатель на виртуальные методы, сама таблица статическая.

У тебя в main.c, например, много ручного приведения типов. А это не только хуже читается, но и опасно.

С этим согласен, контроль за приведение указателя на производный класс к указателю на базовый класс ложится на разработчика. По сути, это требуется только в одном случае - при создании объекта. Во всех остальных случаях в main.c (в примере) это не типовой случай. В C++ неявное приведение базового типа к производному также не возможно.

backbone ★★★★★
()
Ответ на: комментарий от backbone

Реализуется модулями, как отметили выше

Ну вот ты и теряешь скорость на вызове функции (которая не инлайнится) вместо прямого доступа к полю.

сама таблица статическая

В общем случае заполнить эту таблицу статично в C трудно. В случае множественного наследования не уверен, что возможно (не превратив код в полуассемблерную кашу).

У тебя очень простая и статичная иерархия типов, методы не наследуются. А ты подумай, что будет, если дерево типов высокое, и к тому же иерархия меняется по ходу дела? Как ты будешь поддерживать vtbl в актуальном состоянии?

В этом же случае ручное приведение типов даже снизу вверх убивает код. А оно нередко бывает нужно.

unsigned ★★★★
()
Ответ на: комментарий от Norgat

(2) разрушается наследованием когда наследник имеет футпринт родителя в своём составе.

qulinxao ★★☆
()
Ответ на: комментарий от unsigned

решать задачи/проблемы по мере поступления не?

qulinxao ★★☆
()
Ответ на: комментарий от unsigned

Ну вот ты и теряешь скорость на вызове функции (которая не инлайнится) вместо прямого доступа к полю.

Private-метод/функция может инлайнится только в функции, находящиеся в данном модуле. Если встраивать её во внешнюю по отношению к классу/модулю функцию, чревато глюками при разбиении кода на библиотеки, в независимости от ЯП. Поэтому inline указан только для врапперов, содержимое которых неизменно.

В общем случае заполнить эту таблицу статично в C трудно. В случае множественного наследования не уверен, что возможно (не превратив код в полуассемблерную кашу).

Нетрудно. А часто возникает _необходимость_ множественного наследования?

У тебя очень простая и статичная иерархия типов,

Это простой пример, есть практический пример, но код открыть не могу.

методы не наследуются.

Виртуальные функции используются для «неопределённого поведения». Что касается перегрузки функций, считаю тоже злом.

А ты подумай, что будет, если дерево типов высокое, и к тому же иерархия меняется по ходу дела? Как ты будешь поддерживать vtbl в актуальном состоянии?

Если нет желания писать на чистом C, можно включить fms-extensions и записывать декларации для методов и полей в том же виде, как в C++, только читаться это будет хуже, так как в заголовочном файле мы видим только члены данного класса, а чтобы узнать все открытые члены, мы должны посмотреть в родительский класс и т.д.
Если иерархия меняется очень часто, то она плохо продумана, проблемы будут в любом ЯП.

Если дерево типов высокое, значит изначально использовался объектно-ориентированный подход, его и следует придерживаться в дальнейшем...

backbone ★★★★★
()

Вот у меня в рогалике на данный момент нет ни одно класса. Везде обхожусь методами.

Что то я не понял. Методы есть, а классов нет?

andreyu ★★★★★
()
Ответ на: комментарий от backbone

Непонятно зачем писать на С, то что сделано в ++? Разве, что только из-за слепого упорства. К тому же шаблоны добро и няши, язык в языке, они позволяют делать очень красивые вещи и ругаться на тебя в compile time (речь не совсем об это, но все же).

anonymous
()
Ответ на: комментарий от anonymous

Непонятно зачем писать на С, то что сделано в ++? Разве, что только из-за слепого упорства. К тому же шаблоны добро и няши, язык в языке, они позволяют делать очень красивые вещи и ругаться на тебя в compile time (речь не совсем об это, но все же).

Лично я не предлагал писать на C то, что сделано в C++, иначе это будет C++. Я лишь отметил, что важные механизмы ООП реализуются и в C, попытка использоывать все возможные паттерны просто благодаря их существованию и есть слепое упорство.
Шаблоны добро и няши только внутри одного закрытого модуля/класса/библиотеки. В остальных случаях они позволяют делать очень странные и трудно понимаемые вещи, ругаясь трудно разборчивым языком на тебя, вызывая большой compile time при разборе дикой иерархии из hpp. (преувиличил, но всё же)

backbone ★★★★★
()
Ответ на: комментарий от andreyu

А автор так обычные функции называет, которые не member function и даже не друзья (хотя и те даже с натяжкой не методы), а просто.

Может быть это такая традиция в русских переводах по С++ : особр не вдаваясь в суть вообще все функции называть методами?

anonymous
()
Ответ на: комментарий от anonymous

Может быть это такая традиция в русских переводах по С++ : особр не вдаваясь в суть вообще все функции называть методами?

Может это традиция не мешать функциональный и объектно-ориентированный подходы? ;-)

backbone ★★★★★
()
Ответ на: комментарий от anonymous

Уточнение: в современных переводах.

P.S. Да нет, вот страус 2006-го года:

«Виртуальную функцию-член иногда называют методом».

Больше слово метод как синоним слово «функция» нигде не встречается. Так что оппа, это значит автор чего-то не так понял.

anonymous
()
Ответ на: комментарий от backbone

Не пересекается. Функция - это функция, а метод - это виртуальная функция класса.

anonymous
()

Классы не обязательны.

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

у тебя в сырцах нет типов class - но разделение на разные типы и поведение связоное с типом есть - так что вполне ооп.

qulinxao ★★☆
()
Ответ на: комментарий от anonymous

И, кстати, автору: не идут классы, да и хрен с ними. Никто ж не заставляет. На С++ можно и в процедурном стиле писать, такой Си со ссылками и более строгой проверкой типов. Плюс stl с контейнерами и прочими алгоритмами. С++ он такой, он многогранный.

anonymous
()
Ответ на: комментарий от backbone

Мне понятна ваша точка зрения.

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

В шаблонах часто вполне естественная потребность - «мне все равно, кто вы, полезайте в автобус», но если они не нужны, то, действительно, не нужно их впихивать.

anonymous
()
Ответ на: комментарий от unsigned

Краткостью и количеством мест, где ошибиться можно.

Gorthauer ★★★★★
()
Ответ на: комментарий от backbone

Скорости разработки, может быть, но не скорости выполнения.

Вот не факт, не факт. С++ компилятор имеет больше информации о ситуации и может круче оптимизировать.

Gorthauer ★★★★★
()
Ответ на: комментарий от backbone

Можно придерживаться функционального подхода и там, где требуется какой-то механизм, например, полиморфизм, реализовать виртуальные методы.

функциональный... Си... /0

Gorthauer ★★★★★
()

Полиморфизма на таких не напасешься

vertexua ★★★★★
()
Ответ на: комментарий от PiPi

Каким образом такой класс присутствует в реальном мире?

class Comparator {
public:
    virtual int compare(Object* obj1, Object* obj2) = 0;
};

И что из Платона почитать, дабы понять, что объект в ООП является представлением объекта реального мира? Может быть «Государство»? Или «Апологию Сократа»?

generator ★★★
()
Ответ на: комментарий от PiPi

Ну как же. Вот у нас есть матрицы, кватернионы, просто целые числа итд. И все это моноиды по сложению. Значит есть абстрактрая операция add и геттер zero. И вполне можно работать с данными зная только что это моноид без конкретного знания какой именно. По моему мнению ООП в сторогом его понимании и было изобретено как раз в 18 веке. Но люди утеряли оригинальный смысла именно ЯП которые бы поддержали некую запись axiom \a, b -> a + b == b + a раз 2 и опчелся

bga_ ★★★★
()
Ответ на: комментарий от PiPi

Ну и ладно:)

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

generator ★★★
()
Ответ на: комментарий от anonymous

И кстати, а вы сами С++ со смолтолком не путаете? Мультипарадигма, там. Слышали?

О smalltalk толком ничего не знаю, кроме того, что он ближе к ООП и использует механизм сообщений. Плюс, то, что его создатель пытался на его основе ОС написать. Больше ничего не знаю.
«Парадигма» слышал только; мутьтипарадигма у меня ассоциируется только с Чокнутым (мультик такой диснейевский).

backbone ★★★★★
()
Ответ на: комментарий от Gorthauer

Вот не факт, не факт. С++ компилятор имеет больше информации о ситуации и может круче оптимизировать.

В примере конкретная ситуация со статической структурой, содержащей указатели на функции. Как компилятор C++ может круче оптимизировать виртуальные функции?

backbone ★★★★★
()
Ответ на: комментарий от Gorthauer

функциональный... Си... /0

Си - процедурный язык, при разработке может использоваться функциональный подход.

backbone ★★★★★
()
Ответ на: комментарий от quantum-troll

Аналогичный подход в go называется интерфейсами

Я бы не стал называть Go-интерфейсы аналогом тайпклассов Haskell'а.

korvin_ ★★★★★
()
Ответ на: комментарий от backbone

Больше ничего не знаю.

Историю-то знать полезно. В первую очередь для того, чтобы велосипеды не изобретать, и в тысячный раз недоделанную «типа объектную» модель на Си не натягивать.

ассоциируется только с Чокнутым (мультик такой диснейевский).

Плохо, чо. Ну да кому щаз легко.

Автор функции вне класса методами называет, у вас слово «функция» вообще с функциональным программированием ассоциируется.

anonymous
()
Ответ на: комментарий от korvin_

И в чём же существенное отличие?
inb4: Всё, что вызвано алгебраическими типами

quantum-troll ★★★★★
()
Ответ на: комментарий от anonymous

Автор функции вне класса методами называет, у вас слово «функция» вообще с функциональным программированием ассоциируется.

Попробуйте слово «ПРОЦЕДУРА».

quantum-troll ★★★★★
()
Ответ на: комментарий от backbone

Си - процедурный язык, при разработке может использоваться функциональный подход.

Брр... Сон разума рождает этих самых. Поттерингов.

anonymous
()
Ответ на: комментарий от quantum-troll

Неа, не нравится. Функция няшнее. «Процедура» - убогое слово, с процедурами - в процедурный кабинет.

anonymous
()
Ответ на: комментарий от anonymous

Плюс слово «функция» точнее отражает суть.

А то давайте ещё «подпрограммы» вспомним. Subroutines, чо.

anonymous
()
Ответ на: комментарий от anonymous

Историю-то знать полезно. В первую очередь для того, чтобы велосипеды не изобретать, и в тысячный раз недоделанную «типа объектную» модель на Си не натягивать.

Я уже выше отписал, что объектную модель не натягиваю, в одном проекте есть _необходимость_ неограниченно наращивать число модулей. В данный момент интерфейсом к каждому модулю служат пара массивов со строковыми указателями и указатель на функцию Create ().
Если не применить ту извращённую схему с vtable, интерфейс взаимодействия с модулями и между модулями имел бы неудобную форму записи вида module_ptr->functions.function (...), а так всё выглядит как простой вызов функции function (module_ptr), не расходует лишней памяти на указатели для каждой функции внутри элемента данных.

Плохо, чо. Ну да кому щаз легко.

Так плохо, что не до шуток...

Автор функции вне класса методами называет, у вас слово «функция» вообще с функциональным программированием ассоциируется.

Просто у меня слово «процедура» ассоциируется с тем, что выполняет операции над неизвестно чем, находящемся неизвестно где, поэтому, производное от него «процедурный», стараюсь заменять на «функциональный», хотя конечно это не подразумевает функциональное программирование, как его принято понимать в математическом смысле или в контексте Lisp или Haskell.

backbone ★★★★★
()

Если так судить, задаю встречный вопрос: «Зачем нужен C и методы, когда вместо них можно обойтись ассемблером и процедурами?»

Dikar ★★
()
Ответ на: комментарий от generator

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

Можно пример? непонимаю

Я же не говорю про какие-то конкретные сущности из реального мира, говорю лишь про категории мышления. Есть «стол», у него есть свойство «цвет», он является «мебелью», у каждой «мебели» есть свойство «вес» и операции «разобрать»/«собрать» , которые для каждого типа мебели свои итдитп... — это вполне естественные абстракции для человеческого мозга. И создавать умозримые сущности используя подобный подход - естественно. Разве нет?

PiPi
()
Ответ на: комментарий от PiPi

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

Можно пример? непонимаю

Наверное говорят о неоднозначностях. К примеру, параллелограмм - частный случай трапеции, значит класс parallelogram должен быть производным от класса trapezium. Хотя ни тот, ни другой никак не связаны друг с другом.

backbone ★★★★★
()
Ответ на: комментарий от backbone

Private-метод/функция может инлайнится только в функции, находящиеся в данном модуле

А это может быть и открытый метод. Например:

class A {
    int _a;
  public:
    int geta() const { return _a; }
};
Геттер заинлайнится, а в C инлайна не добиться, не потеряв закрытость.

Если встраивать её во внешнюю по отношению к классу/модулю функцию, чревато глюками при разбиении кода на библиотеки

Не уверен, что понимаю. Во всех библиотеках полно таких методов, как я показал. И они вполне инлайнятся откуда угодно.

Нетрудно

Можешь показать? Например, унаследуй свой ромб ещё и от IDisposable.

А часто возникает _необходимость_ множественного наследования?

Вряд ли, если есть множественные интерфейсы. У тебя есть? )

Что касается перегрузки функций, считаю тоже злом

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

Если иерархия меняется очень часто, то она плохо продумана, проблемы будут в любом ЯП

В C++ проблем будет гораздо меньше: виртуальные таблицы будут заполнены правильно, и компилятор предупредит обо всех теперь невалидных приведениях типов.

Кстати,

git.backbone.ws использует недействительный сертификат безопасности. Сертификат действителен только для следующих имён: hg.backbone.ws, backbone.ws

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Вообще я не спорю, что в C возможно ООП - сам люблю этим заниматься. Просто хотел показать, что не всё можно сделать в C, что можно в C++.

unsigned ★★★★
()
Ответ на: комментарий от korvin_

Кстати, не подскажешь, можно ли где-нибудь скачать электронную версию?

Я не нашёл. Заказывал на амазоне.

Miguel ★★★★★
()
Ответ на: комментарий от unsigned

lolwhat7

u mean : не всё ,что делается в С, делается в С также как С++.

qulinxao ★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.