LINUX.ORG.RU

В чём суть ООП?


3

5

С точки зрения манеры проектирования, а не особенностей реализации С++ там CLOS. Вот например я использую определения классов и даже иногда наследование как узнать пишу ли я в ООП стиле?

★★★★★

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

Напротив, конкретный код должен быть конкретным.

Не К.О., а тавтология.

Во всяком случае, в рамках C++.

Узкие у тебя рамки. Не помещаешься (даже в монитор с трудом пролазишь :)

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

Однако, пишем-то мы IRL конкретный код? Вот и получается, что «обобщённый код» в реальном проекте == сферический конь в вакууме. Во всяком случае, в рамках C++.

В рамках C with Classes.

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

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

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

а я могу в С++ написать

а я могу написать log[«8.3f»]+bar с тем-же результатом
и что?

Факт в том, что iostream достаточно криво выводит форматированные числа, и с этим ты ничего не поделаешь.

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

Факт в том, что iostream достаточно криво выводит форматированные числа, и с этим ты ничего не поделаешь.

Неосиляторы регулярно выносят вердикты, а караван идет :)

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

Иначе кодили б щас GUI макросами на асме.

некоторые вещи и сегодня удобно кодить макросами на асме, т.ч. твоя ирония неуместна.

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

Уместна ровно так же, как тот тупак, который ты тут выдаешь за «реплики капитана» :)

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

Не при чем. Просто использование ООП - не какая-то насущная необходимость в С++ (как и «запрет» на невиртуальные деструкторы зависит лишь от использования виртуальных методов, что не есть обязательно). Парадигма под задачу, а не задача под парадигму.

Вот только я не понимаю, зачем тебе C++, если ты не используешь ООП? Давай вернёмся к iostream, разве для них ООП нужно? Что, fopen/fread/fwrite/fclose/fprintf/fscanf недостаточно? Какие плюсы даёт iostream перед ними? Кто запрещает тебе юзать <stdio.h> в проекте на С++ (если тебе именно printf нужен)?

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

твои манипуляторы, суть - костыли.

Суть костыли - это твоя слака, убогий. Повторяю, для неосиливших чтение:

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

Причём, манипуляторы можно передать в качестве параметра в функцию, скомбинировать, сохранить при конструировании функтора и т.п. А тебе придётся при изменении формата перелопачивать все свои printf. Ах да,

Не люблю, когда за меня делают мою работу.

Попутного ветра в горбатую спину, неосиляторы должны страдать и радовать других своей упоротостью.

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

Почему не использую? Использую. Просто не делаю трагедии из iostream, тем более что с ООП его устройство связано чуть менее чем никак :)

Кто запрещает тебе юзать <stdio.h> в проекте на С++ (если тебе именно printf нужен)?

Все дело в этом «если» :) Не нужен - не пользуюсь :)

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

По сравнению с кем?

ООП даёт профит в достаточно сложных задачах, когда есть смысл инкапсулировать множество свойств в один класс, и множество методов во множество связанных интерфейсов (абстрактных базовых классов). Если в этом случае не юзать ООП, то получится WinAPI, в котором Over9000 функций, разобраться в которых нет никакой возможности (самой мысы пришлось придумывать MFC и прочие разнообразные обёртки)

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

нельзя делать невиртуальные деструкторы

можно. если класс не предполагает полиморфного поведения, зачем ему лишняя vtbl?

ИМХО нельзя

независимо от твоего ИМХО, любой шаблонный код в C++ так и работает (кроме трюков вроде CRTP)

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

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

это действительно так, но только в том случае, если тебе нужно выводить небольшой фиксированный диапазон типов (int, double, chars, и т.д.). В принципе в консоль больше ничего и не нужно выводить обычно, но мир не заканчивается на терминале.

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

Суть костыли - это твоя слака

Ну у вас и обобщения :) Веско, но не по теме.

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

Неосиляторы регулярно выносят вердикты, а караван идет :)

не вижу, как он идёт. Мало кто юзает этот ваш std::ostream::operator<<, разве что в хэлловолдах, да в учебниках.

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

множество методов во множество связанных интерфейсов

man декомпозиция :) Понижение связности рулит, и далеко не все задачи можно натянуть на твое любимое ООП.

самой мысы пришлось придумывать MFC и прочие разнообразные обёртки

А еще ATL с WTL (с экстенсивным использованием CRTP внутре), когда появилась STL с фатальным недостатком внутре :) То же мне «аргументация от оффтопика».

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

Мало кто юзает этот ваш std::ostream::operator<<

Конечно, они пишут свои operator<< для своих реализаций же :)

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

Суть костыли - это твоя слака, убогий.

зависть рождает ненависть...

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

я это знаю. А мне оно надо? Неа. В одной строке я хочу выводить дробные, строки,целые и опять строки. Стока из 20 double как-то не смотрится, лучше уж тогда график нарисовать.

А тебе придётся при изменении формата

а тебе придётся менять то, что ты там скомбинировал, и сохранил в 35и местах кода по разным файлам.

Попутного ветра в горбатую спину, неосиляторы должны страдать и радовать других своей упоротостью.

и в каком месте я «страдаю»?

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

это действительно так, но только в том случае, если тебе нужно выводить небольшой фиксированный диапазон типов

Это только если используемый язык достаточно убог (как С, например). boost::format уже расширяемый, хотя бы за счёт перегрузки operator<<.

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

и в каком месте я «страдаю»?

Ну, судя по треду - наслаждаешься, ага.

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

Вот скажи, а если у меня есть объект точка (пара координат), и я хочу её вывести в консоль, на поверхность в OpenGL, отправить по сети и т.п., мне надо добавить все соответствующие методы в класс точки, да?

[Пропущен высер про автобус и офис. Ты там завязывай с веществами.]

Точка слишком незначительна, что-бы ей лично слать сообщение. Потому точки обычно являются частью более общего объекта, например полигона, к которому и обращаются, со всеме вышеперечисленными целями.

То есть в класс полигона (обертка над массивом точек) нужно засунуть функциональность по работе с OpenGL, сетью и всем на свете, что может понадобится. Ок, чего уж там. Эталонное невежество. Уже представляю, как ты множественно наследуешь полигон от какого-нибудь говна с говорящим названием TNetwork, CDataBase и т.п.

Дуй в толксы, там очень не хватает твоего авторитетного мнения про kickstarter, Qt5, kde4, gnome3, Пульсаудио и т.п.

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

Почему не использую? Использую. Просто не делаю трагедии из iostream, тем более что с ООП его устройство связано чуть менее чем никак :)

дык и я не делаю трагедии (:

Все дело в этом «если» :) Не нужен - не пользуюсь :)

именно! речь о том и идёт, что ЕСЛИ тебе нужен printf(3), то нужно юзать printf(3), и пофиг, что это не ООП ни разу. Что до iostream, то пусть будет, я не против, просто это задача из тех, для которых лучше писать свою printf, а не свой iostream (у нас есть и то и другое, потому мы можем сравнивать).

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

а тебе придётся менять то, что ты там скомбинировал, и сохранил в 35и местах кода по разным файлам.

А тебе форматные строки, которые ты написал в 35 местах кода по разным файлам не придётся править?

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

можно. если класс не предполагает полиморфного поведения, зачем ему лишняя vtbl?

а если кто-то решит такое полиморфное поведение получить? ИМХО, если у тебя есть какая-то структура, которая не предполагает полиморфизма, то что не записать struct? (например если это struct Point{ int x; int y;}; ) ИМХО класс в C++ изначально предполагает, что от него будут что-то там наследовать.

независимо от твоего ИМХО, любой шаблонный код в C++ так и работает (кроме трюков вроде CRTP)

шаблонный код не раскрывается в рантайме, а эта ваша утиная типизация раскрывается. Для меня это принципиальное различие, и именно про неё было сказано «нельзя». шаблоны - это совсем другое.

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

а если кто-то решит такое полиморфное поведение получить?

премия Дарвина, чо :)

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

man декомпозиция :) Понижение связности рулит, и далеко не все задачи можно натянуть на твое любимое ООП.

а я и не предлагал ВСЕ задачи натягивать на ООП. Как раз наоборот.

А еще ATL с WTL (с экстенсивным использованием CRTP внутре), когда появилась STL с фатальным недостатком внутре :) То же мне «аргументация от оффтопика».

что не так в аргументации? WinAPI проектировался ещё до ООП, и мы видим, в какое УГ он превратился.

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

Конечно, они пишут свои operator<< для своих реализаций же :)

причём тут operator<<?

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

Это только если используемый язык достаточно убог (как С, например).

для fprintf(3) его вполне хватает.

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

а если кто-то решит такое полиморфное поведение получить?

А какое динамически полиморфное поведение можно получить от класса без виртуальных функций?

ИМХО, если у тебя есть какая-то структура, которая не предполагает полиморфизма, то что не записать struct?

И открыть всю реалиазцию? Зачем это для контейнеров, например? Или ты предпочитаешь писать

struct Foo
{
private:
....
};

вместо

class Foo
{
....
};

а эта ваша утиная типизация раскрывается

Утиная типизациия заключается в том, что проверяется наличие членов типа или операций на нем, а не отношения типа с другими, а когда эта проверка осуществляется несущественно.

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

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

ну если тебе делать нечего - добавляй. Обычно так не делают.

Ок, чего уж там. Эталонное невежество.

у тебя-то? да... Хотя фантазия у тебя богатая, не думал, что из моих слов можно столько нафантазировать...

Уже представляю, как ты множественно наследуешь полигон от какого-нибудь говна с говорящим названием TNetwork, CDataBase и т.п.

...и всё это от XActralBase...

Без него - никак.

Дуй в толксы, там очень не хватает твоего авторитетного мнения про kickstarter, Qt5, kde4, gnome3, Пульсаудио и т.п.

сейчас пойду, отпишусь про systemd (:

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

То, что никто не принуждает тебя пользоваться напрямую WinAPI в 2012 году, когда в моде внезапно кроссплатформенность :) Не умеешь в WinAPI - оставь это людям, которые пишут фреймворки. Не нравятся фреймворки - напиши свой, «более лучше удобный». Это же опенсурс :)(или «очки запотели»(с)?).

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

А тебе форматные строки, которые ты написал в 35 местах кода по разным файлам не придётся править?

придётся. Но мне проще найти строку «Неизвестная ошибка в строке %d», чем искать какую-то НЁХ в 35и файлах. Ну а кроме сообщений об ошибках я не знаю, что ещё в консоль выводить...

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

а если кто-то решит такое полиморфное поведение получить?

тебя научить запрещать наследование в C++? или наследоваться от класса, который этого не предполагает, ты считаешь меньшим быдлокодом?

что не записать struct?

struct и class в C++ - синонимы с точностью до квалификаторов доступа. наследоваться от структуры никто не мешает

утиная типизация раскрывается

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

твои претензии, как мне кажется, против динамической типизации, а не утиной

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

О, пошли нелепые отмазки.

Вот скажи, а если у меня есть объект точка (пара координат), и я хочу её вывести в консоль, на поверхность в OpenGL, отправить по сети и т.п., мне надо добавить все соответствующие методы в класс точки, да?

Точка слишком незначительна, что-бы ей лично слать сообщение. Потому точки обычно являются частью более общего объекта, например полигона, к которому и обращаются, со всеме вышеперечисленными целями.

И через пол часа:

Обычно так не делают.

сейчас пойду, отпишусь про systemd (:

И не возвращайся. Слишком много жира, и слишком мало знаний в области обсуждения.

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

твои претензии, как мне кажется, против динамической типизации, а не утиной

Шаблоны Си++ уже считаются утиной типизацией?

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

А какое динамически полиморфное поведение можно получить от класса без виртуальных функций?

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

И открыть всю реалиазцию?

если тебе нужна закрытая структура - закрой эту структуру.

Или ты предпочитаешь писать

я предпочитаю писать

class Foo
{
private:
....
public:
....
};

struct Boo
{
.....
};

Утиная типизациия заключается в том, что проверяется наличие членов типа или операций на нем, а не отношения типа с другими, а когда эта проверка осуществляется несущественно.

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

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

напрямую WinAPI

Это же опенсурс

делить на ноль нельзя.

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

тебя научить запрещать наследование в C++?

про final я в курсе.

или наследоваться от класса, который этого не предполагает, ты считаешь меньшим быдлокодом?

зависит от задачи.

struct и class в C++ - синонимы с точностью до квалификаторов доступа. наследоваться от структуры никто не мешает

я знаю, что синтаксис это позволяет. Синтаксис вообще многое позволяет, но тривиальные структуры, которые не предполагают полиморфизма и частичной инкапсуляции ИМХО следует называть struct. Если тебе нужно структуру полностью скрыть - её можно полностью скрыть. А если часть методов у тебя наружу, то это ИМХО уже класс, который годен для наследования (по умолчанию).

твои претензии, как мне кажется, против динамической типизации, а не утиной

в принципе - да. Я против _неуправляемой_ динамической типизации, типа утиной. Однако, я не против динамической типизации, когда она управляется наследованием от моего базового класса. Т.е. ты можешь взять мою коллекцию, и пихать туда все свои элементы, но КАЖДЫЙ твой элемент в моей коллекции обязан поддерживать те методы, которые я заповедовал в своём базовом классе. КАК именно твои классы будут это делать - меня не волнует. Однако, если использовать утиную типизацию, то в мою коллекцию можно засунуть любую похожую НЁХ, что приведёт к непредсказуемым ошибкам в рантайме.

Что до шаблонов - то они как макросы, просто возможность поменьше писать одно и то же.

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

никто не говорил. у меня своё мнение имеется. А что не так?

То что ООП - это парадигма проектирования впервую очередь, а не синтаксис ЯП. Надо осознать разницу между концепцией и реализацией. Надо понять, чем на самом деле явлется интерфейс, а что такое функции члены.

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

О, пошли нелепые отмазки.

нет. Просто ты до того довёл мои слова до абсурда.

И не возвращайся. Слишком много жира, и слишком мало знаний в области обсуждения.

как скажешь. У тебя так вообще никаких знаний нет, либо ты их тщательно скрываешь.

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

а кто тебе сказал, что в производном классе не будет виртуальных функций?

Тогда ты будешь использовать указатели на тот производный класс, а не на базовый, и в нём же сделаешь виртуальный деструктор.

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

Шаблоны Си++ уже считаются утиной типизацией?

ну на них можно накостылять что-то похожее. См. выше. Правда не в рантайме.

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

и при чём тут ООП?

Виртуальные деструкторы тоже особо с ООП не связаны. Точнее они связаны с реализацией ООП в С++, но никак не парадигмой ООП.

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

То что ООП - это парадигма проектирования впервую очередь, а не синтаксис ЯП.

ну и?

Надо понять, чем на самом деле явлется интерфейс, а что такое функции члены.

C++ класс с открытыми функциями-членами не является интерфейсом?

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

Template, or generic functions or methods apply the duck test in a static typing context

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

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

Тогда ты будешь использовать указатели на тот производный класс, а не на базовый, и в нём же сделаешь виртуальный деструктор.

тогда производный деструктор вызовется, а вот деструктор базового класса - нет. Деструкторы не наследуются. Потому их и надо делать виртуальными.

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