<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3919554</guid>
        <pubDate>Thu, 20 Mar 2025 13:19:13 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3919554</link>
        <description><![CDATA[Qraizer: Ну так это просто первые фразы. Тезисы, т.с. На одних тезисах далеко не уедешь, их можно использовать как набросок плана для дискуссии, но сама дискуссия без развёрнутой аргументации не выдержит напора критически мыслящего оппонента.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3919491</guid>
        <pubDate>Thu, 20 Mar 2025 06:23:55 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3919491</link>
        <description><![CDATA[Majestio: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=445466&view=findpost&p=3904751'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Qraizer &#064; <time class="tag-quote__quoted-time" datetime="2024-05-24T18:05:49+00:00">24.05.24, 18:05</time></span><div class='quote '>the finalization</div></div><br>
<strong class='tag-b'>Qraizer</strong>, прива&#33;<br>
<br>
Получил я мало-мало доступ к проф-версии ChatGPT (o3-mini-high), очень &quot;мудрой в программировании&quot;, и крайне жадной к деньгам. И задал ему бесплатно :lool: задание (нашёл разовую лазейку). Попросил выдать максимально кратное резюме по твоему посту в этом топике, мол &quot;выдели самое существенное&quot;. Получил вот такой ответ:<br>
<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><ul class="tag-list"><li> Интерфейсы облегчают планирование, но усложняют разработку из-за жесткой неизменности после публикации.</li><li> Любое изменение интерфейса приводит к значительным затратам на регрессионное тестирование и рефакторинг.</li><li> Грамотное использование интерфейсов требует значительного опыта и часто подразумевает участие лидов.</li><li> Абстрактные классы могут имитировать интерфейсы, предоставляя возможность частичной реализации и добавления полей.</li></ul></div></div><br>
Плс, оцени работу этого ИИ - он нашёл существенное, или это всеж очередная &quot;профонация&quot; от ИИ. <br>
Они это щяс умеют просто ппц :lol:]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904762</guid>
        <pubDate>Sun, 26 May 2024 22:04:09 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904762</link>
        <description><![CDATA[Majestio: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=445466&view=findpost&p=3904760'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>H g &#064; <time class="tag-quote__quoted-time" datetime="2024-05-26T17:16:10+00:00">26.05.24, 17:16</time></span><div class='quote '>Если заинтересовали значит, Вас же что-то не устраивает в С++ или ищете возможности делать то же самое с меньшими трудозатратами, иначе зачем ? Ведь можно потратить время (которое вы потратите на изучение) на то, чтобы сделать что-то полезное уже знакомым инструментом.</div></div><br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=445466&view=findpost&p=3904761'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ЫукпШ &#064; <time class="tag-quote__quoted-time" datetime="2024-05-26T21:29:11+00:00">26.05.24, 21:29</time></span><div class='quote '>Ты серьёзно увеличишь производительность труда и качество результата,<br>
если то же самое будешь делать на с++.</div></div><br>
Для разработок под мобильные платформы - это не совсем так, равно как и под WEB. В этом плане Dart, с его возможностями создания приложений под разные платформы, гораздо мощнее С++. Я пробовал использовать С++/Qt для сборки программ под Андроид, но это какой-то изврат. Используя Dart, мы получаем нативный байткод, без каких-то &quot;прокси-оболочек&quot; (в качестве GUI-тулкита используется Flutter). Dart мне чем-то напоминает <a class='tag-url' href='https://haxe.org' target='_blank'>Haxe</a>. К сожалению Haxe стартовал гораздо раньше, но развивается крайне медленно. А вот Dart имеет поддержку Google, и его развитие гораздо более быстрое. Важно иметь не просто идею и сырой инструментарий, а что-то, что можно уверенно использовать для продакшена. Haxe я интересовался лет 7-8 назад, тогда это было очень сырое &quot;изделие&quot;. Сейчас не знаю. А вот с Dart+Flutter изначально, с момента моего знакомства, уже можно смело использовать. Ну как-то вот так.]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904761</guid>
        <pubDate>Sun, 26 May 2024 21:29:11 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904761</link>
        <description><![CDATA[ЫукпШ: <strong class='tag-b'>H g</strong>, вариант.<br>
<div class="tag-spoiler spoiler closed"><div class="spoiler_header" onclick="openCloseParent(this)">Скрытый текст</div><div class="body"><br>
Ты серьёзно увеличишь производительность труда  и качество результата,<br>
если то же самое будешь делать на с++.<br>
Фактически, такое мероприятие приведёт к созданию библиотеки<br>
классов, которые можно будет использовать многократно.<br>
При этом нет необходимости делать все возможные классы <br>
сразу - изготавливать их можно по мере необходимости.<br>
Библиотека будет расти постепенно и не потребует каких-то<br>
запредельных трудозатрат.<br>
</div></div>]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904760</guid>
        <pubDate>Sun, 26 May 2024 17:16:10 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904760</link>
        <description><![CDATA[H g: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Да, этот фрэймворк для UI я пользую уже давно в 100% случаях</div></div>Мое скромное мнение:<br>
<div class="tag-spoiler spoiler closed"><div class="spoiler_header" onclick="openCloseParent(this)">Скрытый текст</div><div class="body">Не хочу разводить холивар, считаю что разные способы имеют право быть. Несколько лет назад я пытался установить и настроить Qt, но что-то пошло не так, надоело мне возиться (я не программист и решаю прикладные задачки или пишу игры, но все тонкости современных сред не знаю) и взглянул в сторону написать User Interface на чистом WinAPI и так мне понравилось, что до сих пор пишу на чистом Си и WinAPI. Ну и как бонус программа очень малого размера и быстрая. Правда нет всех вожможностей как у профессиональных контролов из Qt, но мои потребности такой способ удовлетворяет.<br>
//<br>
Как вывод, (опять же это только мое мнение) применение той или иной технологии/парадигмы/языка зависит в первую очередь от задачи. Что-то проще делать на одном языке программирования, а что-то на другом.<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>А вот два других ЯП, которые меня заинтересовали (Rust и Dart)</div></div><br>
Если заинтересовали значит, Вас же что-то не устраивает в С++ или ищете возможности делать то же самое с меньшими трудозатратами, иначе зачем ? Ведь можно потратить время (которое вы потратите на изучение) на то, чтобы сделать что-то полезное уже знакомым инструментом.<br>
</div></div>]]></description>
        <author>H g</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904754</guid>
        <pubDate>Sat, 25 May 2024 09:43:06 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904754</link>
        <description><![CDATA[Majestio: <strong class='tag-b'>Qraizer</strong>, большое спасибо, что не поленился так объемно, и так подробно расписать&#33; Кому как эта тема зайдет, а я заинтересовался жЫрнотой Qt. Да, этот фрэймворк для UI я пользую уже давно в 100% случаях. Но его жЫрнота меня расстраивает. Захотелось его как-то оценить с точки зрения современных подходов проектирования. Давно как-то попался интересный альтернативный проект для создания GUI - <a class='tag-url' href='https://github.com/cnjinhao/nana' target='_blank'>Nana</a> (<a class='tag-url' href='https://qpcr4vir.github.io/nana-doxy/html/index.html' target='_blank'>мануальчик</a>). Мои эксперименты показали, что при использовании Nana, размер собранного проекта примерно в 20-25 раз меньше, чем тоже самое можно получить с помощью Qt. Уверен, что и wxWidgets по количеству жЫра очень близок к Qt. Чтобы избежать всяких кривотолков - я использовал строго статическую линковку, с последующим strip исполняемых модулей. <br>
<br>
Да, у всех перечисленных выше проектов своя история и свои скелеты в шкафу. Которые тянутся от релиза к релизу. Не знаю на сколько последняя версия Qt требует последних стандартов С++, но точно помню, что свои разработки они начали вести еще задолго до появления С++11. Оттуда их реализация сигналов-слотов c использованием мета-объектной информации и использовании для этого MOC. А это уже не С++, а С++ с костылями. В Nana такого нет, ибо стартанул проект с обязательным требованием С++11 и выше. Там взаимодействие строится на лямбдах с замыканиями. Может визуально это смотрится более громоздко, чем современный синтаксис connect от Qt, но не требует дополнительного мета-барахла. Ну это так ... немного оффтопик. <br>
<br>
Ну а стартанул я эту тему в разделе С++ т.к. с этим ЯП я на &quot;ты&quot;, ну или почти. А вот два других ЯП, которые меня заинтересовали (Rust и Dart) у меня пока в стадии знакомства. Пытаюсь спроецировать свои знания из С++ на них. Но, ясный перец, языки разные, где-то совсем разные. Поэтому решил, скажем так, рассматривать их с более высокой ступеньки абстракции - с подходов к проектированию. А иначе совсем туман.<br>
<br>
Вощем, твои ответы будем почитать наверное еще много раз. Как говорят &quot;диавол кроется в мелочах&quot;, а они не все и не всегда в зоне внимания.<br>
<br>
ЗЫ: Тему считаю раскрытой, но топик не закрываю - мож кто еще решит высказаться. Но, в целом, я доволен&#33; :lol:]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904751</guid>
        <pubDate>Fri, 24 May 2024 18:05:49 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904751</link>
        <description><![CDATA[Qraizer: <span class="tag-color tag-color-named" data-value="gray" style="color: gray">the finalization</span><ul class="tag-list"><li>Интерфейсы – это больная тема всегда. Г.о. потому что они упрощают планирование и при этом усложняют разработку. Нет, не надо понимать это превратно. Интерфейсы мастхэв, но требуют грамотного подхода. Очень грамотного. Студент всяко не осилит без кучи больных шишек. И джун не осилит. И не каждый сеньор, иначе зачем нужны были бы лиды. Ну кажется, вот счас всё распланируем, декомпозируем задачу на подзадачи, задокументируем интерфейсы взаимодействия между ними, раскидаем каждую подзадачу отдельному сотруднику и пойдём пить кофе и получать премию за грамотный менеджмент. Ага, счас.</li></ul>Главное преимущество интерфейсов – абсолютное абстрагирование от реализации – одновременно и главный их недостаток: после публикации их категорически нельзя менять. Ну не то, чтобы совсем нельзя, но любая правка интерфейса влечёт уйму работы по регрешну и рефакторингу, т.е. правки интерфейсов очень дороги. Ситуация как с наследованием, сильная связь интерфейса с его реализациями налицо. (Не удивительно поэтому, что реализация интерфейса практически повсеместно является публичным производным классом от класса, этот интерфейс документирующего.) Не ну а как иначе-то, если они сильно связаны. Та и вообще, ровно для того, чтобы быть неизменными, интерфейсы и создаются, ибо ну а зачем они иначе нужны вообще. Так что это не недостаток, нет, я не так выразился.<br>
Недостаток в том, что планировать надо в самом начале, и неудачно спланировать раз плюнуть, вот и приходится иногда перепланировать. А чтобы не было неудачно, нужно много шишек, причём через опыт, и желательно собственный, т.к. чужой усваивается плохо, а значит и книжки плохо помогают. Лично мне осознать помог лишь один случай, когда пришлось двухнедельную работу просто удалить и всё начать заново. Ох, я ходил курить раза три, панелька &quot;Аре йоу суре ту делит зис перфект анд вондерфул директори?&quot; в файловом менеджере висела минут сорок, всё не решался нажать ок.<br>
Короче, это всё лирика. Хотя и не без пользы, за недостатки ж, как-никак. Самый прямой вариант документирования интерфейсов наличествует в практически любом языке. Interface ICoolProtocol { и вперёд вплоть до }; пишем <s class='tag-s'>всякую фигню, лишь бы скомпилилось, потом разберёмся</s> в смысле свои лидовые договорённости с сеньорами. Ну а сеньоры такие &quot;ок<s class='tag-s'>&quot;, раскидали эти Interface своим джуниорам и пошли за премией. Нуачё, они ж не лиды, не им за убытки на ковре в позе, им можно.</s><span class="tag-color tag-color-named" data-value="gray" style="color: gray"> тьфу-ты </span>:angry: , только у нас Плюсы, у нас нет интерфейсов&quot;. И тут ты такой как лид &quot;ок, тогда вы все прямиком в джуны с завтрашнего дня, если до сегодняшнего вечера не пересдадите собес у эйчара<span class="tag-color tag-color-named" data-value="gray" style="color: gray">, придурки</span>&quot; последнее шёпотом, ибо корпоративная матьеё этика. А всё почему.<br>
А потому, что:<ol class="tag-list" type="1"><li>берём и делаем class { public:, можно и просто сразу struct{, короче, с публичным наполнением; ибо зачем нам в документировании интерфейса что-то, чем всё равно не воспользоваться;</li><li>наполняем его методами с virtual в начале и =0 в конце;</li><li>никаких полей в нём не предусматриваем, как и конструкторов; а вот деструктор (хоть и не обязательно, но джуны есть джуны, пусть за ними следит компилятор, а не мы) можно, и тоже virtual, пусть и с пустым телом; всё, мы имеем интерфейс;</li><li>реализующие его производные классы должны его (внезапно) наследовать и наследовать виртуально (и публично? обычно да, и я не представляю, когда может быть выгодно не публично, но фикъего знает) и перекрывать все методы; это реализации интерфейса;</li><li>идём за премией.</li></ol>Абстрактные классы не являются интерфейсами в прямом смысле, но они легко под них мимикрируют. Их экземпляры нельзя создавать сами по себе, даже в составе агрегатов, от них обязательно нужно унаследоваться и создавать уже производные экземпляры. Они документируют интерфейс взаимодействия и не содержат никаких атрибутов. Все вот такие вот =0 чистые методы обязательно перекрываются, а если не все, у нас всё равно получится абстрактный класс, чьи непосредственные экземпляры компилятор создать не позволит. Наследуясь от них виртуально, мы получаем форсирование совмещения экземпляров этого класса в производном вне зависимости от того, сколько раз прямо или опосредовано он встретится в списке базовых. Т.е. всё, что нужно, в них есть. Но в них есть и кое-что ещё, на что интерфейсы неспособны. Например, чистые методы можно реализовать, предоставив т.с. реализацию-по-умолчанию. (Это всё равно не позволит создавать экземпляры таких классов иначе чем в составе реализующих производных классах, ибо =0 никуда не делось.) Они могут иметь атрибуты сиречь поля и конструкторы. Они обязаны наследоваться, но не обязаны публично и/или виртуально. Ну т.е. они просто классы. Зачем оно всё надо? Вообще-то абстрактные классы ИМХО полезны чаще, чем интерфейсы. В конце концов они сами могут производными других классов, не обязательно абстрактных даже, что позволяет использовать их поверх отлаженного легаси. И да, можно реализовать только часть интерфейса, и дореализовать остальное в более верхнем производном. Зачем? А вот в <s class='tag-s'>Африке негров линчуют</s> Плюсах зачем-то так можно, хотя, по правде говоря, частичная реализация интерфейса это как-то странно выглядит. И вот тогда непубличное наследование в этом промежуточном узле иерархии более чем к месту. Но по-любому виртуальное. И даже тем более виртуальное, т.к. совмещение тут выходит на передний план. Ну и невиртуальное наследование тоже ведь применяется. Не всегда ж атрибуты должны совмещаться, иногда они должны и разделяться, тут зависит от разрабатываемой архитектуры комплекса в целом. Правда, к интерфейсам это уже по-любому не относится, но относится к классам с множественными базами вообще, абстрактными в частности.<br>
В заключение могу добавить, что работа с интерфейсами в Плюсах вполне на уровне. Легко можно проверить, поддерживает ли некий класс тот или иной интерфейс, просто сделав ему dynamic_cast&lt;&gt;. В тех же Дельфях, например, AS не даёт той же гибкости, так как не способен на перекрёстные приведения, так что там без API операционной системы, QueryInterface(), например, такого не сделать. Нужно лишь, чтобы класс был полиморфным, ну а куда он денется, коли методы виртуальные. Так, если у тебя коллекция QT-объектов с кучей всяко-разных кастомных пользовательских расширений, и тебе надо их сериализировать, то dynamic_cast&lt;&gt; к каждой кастомизации легко выявит те, которые требуют дополнительных усилий.<br>
Так что я не знаю, когда может быть полезным частичная реализация интерфейса. Теоретически это должно быть плохой практикой, ибо видя перед собой ICoolProtocol в базах, я получу ложное впечатление, что он реализован. Но если вдруг такое нужно... Всё ж лучше разделить исходный интерфейс на части и тогда уж реализовывать их, но каждый полностью. Принцип неизменности интерфейса требует, что чтобы что-то в нём поменять, нужно заводить новый интерфейс. Если изменения касаются лишь добавления функционала, то пусть даже просто как производный от исходного. Типа ICoolProtocol2: virtual public ICoolProtocol. Если же изменения касаются не только добавления, но и подмены имеющегося, то имеет смысл переосмыслить старый функционал и перереализовать его в форме нового, и тогда в реализации-по-умолчанию сделать dynamic_cast&lt;&gt; к новому интерфейсу и заюзать его. В итоге реализации ICoolProtocol2 смогут просто не напрягаться депрекейтед ICoolProtocol. Такое невозможно в интерфейсах, но легко делается на абстрактных классах. Ну а что касается использования, то просто принимаем ICoolProtocol*, если нам достаточно ICoolProtocol, и тогда реализация и ICoolProtocol, и ICoolProtocol2 легко проходят derived to base convertion. А если недостаточно, то явно принимаем ICoolProtocol2*, и тогда вызовы с реализацией только ICoolProtocol не пройдут компиляцию.<br>
Это всё касается динамического полиморфизма. Если есть желание поговорить за статический, то это выходит за рамки того определения. Ну не совсем, но выйдет, когда зайдёт разговор. <br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">Fatality&#33; бдыщь</span>]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904748</guid>
        <pubDate>Fri, 24 May 2024 16:26:22 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904748</link>
        <description><![CDATA[Qraizer: <span class="tag-color tag-color-named" data-value="gray" style="color: gray">It is continue</span><ul class="tag-list"><li>Агрегация мне как плюсовику за пределами C++ практически не встречалась. Обычно подразумевается, что на каких-нибудь условных Крестах или там Дельфях программер просто определяет некий класс полем в своём классе, что, учитывая ссылочность классов в этих языках, автоматически удовлетворяет приведённому определению. При этом, однако, уничтожение экземпляра класса всё равно попутно убъёт и агрегат, т.к. на него больше не будет ссылок. Если же так же поступить в Плюсах, то получится внезапно Композиция. Ибо Плюсы не используют смешанную семантику, и ИМХО это хорошо, т.к. меньше путаницы. (При желании можно любой тип сделать ссылочным, просто добавив &amp; к нему. Строгость и одновременно гибкость Плюсов мне представляется более выгодным качеством, нежели медвежья услуга со стороны языка в лице смешанной семантики.) Тем не менее она обычно всё равно обычно называется агрегацией. Просто потому что, хотя и имеет другую семантику, синтаксически выглядит так же.</li></ul>При желании реализовать настоящую агрегацию раз плюнуть. Типичный пример: архитектура потоков ввода-вывода, принимающих буферизирующий std::basic_streambuf&lt;&gt; в конструкторах std::basic_(i/o)stream&lt;&gt;. Типа создаём свой socket_buf на базе Sockets::SocketClientUDP&lt;&gt; производным от std::stream_buf&lt;&gt;, передаём в конструктор std::ostream и вуаля, пишем в сокет обычными operator&lt;&lt;. Вообще, в Плюсах агрегация часто соседствует с полиморфизмом, т.к. полагается на позднее связывание вкупе с фабриками объектов. Не знаю, мне практически никогда не требовалось. (Да, почти.)<br>
Что же до агрегации в стиле Плюсов, то это более чем обычное дело. Композицией это не называют, потому как выше уже объяснена неоднозначность этого термина. Зато это прекрасная альтернатива наследованию, когда оно избыточно, см. пост о наследовании. Там мы лишаемся недостатка сильной связи, т.к. агрегат с агрегирующим классом связан слабо, только через свой интерфейс. Также от агрегирующего не требуется вести себя подобно агрегату, и при этом никто не мешает завести атрибут агрегата, чтобы передать куда надо. Есть только некая проблема с делегированием методов, но она категорически несложно решается :o препроцессором :D , а для особо грамотных и без оного, на шаблонах с несложным метакодом, при этом &quot;бесплатным&quot; бонусом получаем управляемость делегирования, а не тупо identity forward, т.к. при необходимости identity легко и точечно специализируется.<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">К слову, если кто из неплюсовиков или не очень опытных плюсовиков не понимают, нафика нам вся эта мета. Нет, не потому что можем, а потому, что мы, в отличие от них, понимаем его потенциал и видим, где он полезен. Внезапно – много где и чаще, чем им кажется.</span><br>
Возможность отделить время жизни агрегата от времени жизни его контейнера, равно как и возможность подмены агрегатов в ран-тайм, мне кажется сомнительным преимуществом. Ну, второе ещё куда ни шло, но и это скорее всего приведёт к тому, что контейнер всё равно придётся перезапустить. Пусть и без пересоздания, но всяко с переинициализацией. Что же до первого, то позвольте вопрос: если ли смысл в существовании атрибута отдельно от его объекта? Ну вот создал я socket_buf. И что? Что я сним буду делать вне std::ostream? Не, ну архитектура потоков делает это возможным и даже относительно осмысленным, но часто ли std::stream_bufы используются сами по себе? Можно порыть статистику в гугле, и мне кажется, примерный результат я смогу предсказать. Агрегация в том своём определении ИМХО является архитектурным анахронизмом. С нею можно жить, как и с malloc() + init() вместо operator new. Но надо ли? Впрочем, совсем бесполезной она всё ж не является. Те же потоки и std::locale как пример, однако ж и там при std::basic_ios&lt;&gt;::imbue() следует некислая такая переинициализация, выливающаяся в приличный оверхед.<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">finalization will asap</span>]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904696</guid>
        <pubDate>Thu, 23 May 2024 17:04:30 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904696</link>
        <description><![CDATA[Qraizer: <span class="tag-color tag-color-named" data-value="gray" style="color: gray">continue is here</span><ul class="tag-list"><li>Композиция представляет собой термин, выходящий за рамки ООП. В контексте же ООП он, насколько я помню, применяется нечасто, и причиной тому то, что методик композиции классов далеко не одна. В частности наследование тоже одна из них. Но не простое наследование, а в специфически спроектированной архитектуре. А именно: предварительная декомпозиция на подклассы с последующим их объединением. Причём подразумевается, что одна и та же декомпозированная сущность может быть реализована по-разному.</li></ul>Пример: паттерн &quot;стратегия&quot; в одной из своих возможных вариантах архитектуры. Ну, кто читал Александреску, те понимают хорошо. При этом наследование тут в общем-то не требуется, хотя в зависимости от конкретики оно может быть полезно. В std, например, таковым паттерном является концепция аллокаторов, и наследования там не применяется. (Впрочем, строгого запрета на это нет, просто оно не нужно.)<br>
В качестве примера реализации композиции с наследованием а-ля Александреску могу привести свою библиотечку сокетов. Там что-то вроде:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// служебные классы</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketBase;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class ConnectBase;</div><div class="code_line">template &#60;class, int = AF_INET&#62; class SocketRead;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketWrite;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketServer;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketClient;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketUDP;</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class BroadcastWrite;</div><div class="code_line">// классы для использования</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class BroadcastServer; &nbsp;// слушатель броадкастов</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class BroadcastClient; &nbsp;// рассыльщик броадкастов</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketServerUDP; &nbsp;// читатель датаграм</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketClientUDP; &nbsp;// писатель датаграм</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketServerTCP; &nbsp;// точка подключения для серверов</div><div class="code_line">template &nbsp; &nbsp; &nbsp; &nbsp;&#60;int = AF_INET&#62; class SocketClientTCP; &nbsp;// клиент для подключения к серверу</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>Выглядит жутковато, но право, тому умнику из Беркли, который спроектировал архитектуру сокетов в их виде, я желаю отдельного котла, причём оплаченного им же самим ещё при жизни. Вот кусочки определений (кроме AF_INET, реализаций ещё нет и вряд ли будет):<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">/*</div><div class="code_line">&nbsp;&nbsp; Служебные классы. Не имеют публичного интерфейса, в их задачи входит</div><div class="code_line">&nbsp;&nbsp; предоставление конкретного функционала, запрашиваемого теми или иными</div><div class="code_line">&nbsp;&nbsp; аспектами функциональности сокетов.</div><div class="code_line">*/</div><div class="code_line">&nbsp;</div><div class="code_line">/* Базовый класс сокета. RAII над сокетом.</div><div class="code_line">&nbsp;&nbsp; Занимается только созданием, удалением и хранением состояния последней операции */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketBase &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Базовый класс соединения.</div><div class="code_line">&nbsp;&nbsp; Занимается только подключением к серверу. Броадкаст также возможен. */</div><div class="code_line">template &#60;&#62;</div><div class="code_line">class ConnectBase&#60;AF_INET&#62;: virtual public SocketBase&#60;AF_INET&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Класс стратегии чтения из сокета. Приём на конкретном сконнекченном сокете. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketReadRaw: virtual public SocketBase&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Класс стратегии чтения из сокета. Приём по броадкасту. Сохраняет последнего клиента. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class BroadcastReadRaw: virtual public SocketBase&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет для чтения.</div><div class="code_line">&nbsp;&nbsp; Raw является стратегией чтения (непосредственный клиент/броадкаст). */</div><div class="code_line">template &#60;class Raw, int TYPE&#62;</div><div class="code_line">class SocketRead: virtual public SocketBase&#60;TYPE&#62;, public Raw &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет для записи.</div><div class="code_line">&nbsp;&nbsp; Занимается только записью в сокет. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketWrite: virtual public SocketBase&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Групповой сокет для записи.</div><div class="code_line">&nbsp;&nbsp; Предназначен для броадкастов. Броадкасты не маршрутизируются. */</div><div class="code_line">template &#60;&#62;</div><div class="code_line">class BroadcastWrite&#60;AF_INET&#62;: virtual public SocketBase&#60;AF_INET&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет для серверов. Ориентирован на приём данных.</div><div class="code_line">&nbsp;&nbsp; Собирается из классов сокета, коннекта и чтения с политикой коннекта. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketServer: virtual public ConnectBase&#60; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TYPE&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;public SocketRead &#60;SocketReadRaw&#60;TYPE&#62;, TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет для клиентов. Ориентирован на передачу данных конкретному серверу.</div><div class="code_line">&nbsp;&nbsp; Собирается из классов сокета и конкретной записи. */</div><div class="code_line">template &#60;&#62;</div><div class="code_line">class SocketClient&#60;AF_INET&#62;: public SocketWrite&#60;AF_INET&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Базовый класс для UDP сокетов. Обрабатывает только свойства сокета.</div><div class="code_line">&nbsp;&nbsp; Аналогичный базовый для TCP сокетов не нужен, ибо будет просто пустой. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketUDP: virtual public SocketBase&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/*</div><div class="code_line">&nbsp;&nbsp; Конкретные классы сокетов. Собираются из служебных классов по принципу</div><div class="code_line">&nbsp;&nbsp; требуемой функциональности.</div><div class="code_line">*/</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет UDP для серверов. Умеет только читать. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketServerUDP: public SocketUDP&#60;TYPE&#62;, public SocketServer&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет UDP для клиентов. Умеет только писать. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketClientUDP: public SocketUDP&#60;TYPE&#62;, public SocketClient&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Групповой сокет для клиентов. Умеет только писать, но сразу всем. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class BroadcastClient: public SocketUDP&#60;TYPE&#62;, public BroadcastWrite&#60;TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Групповой сокет для серверов. Умеет только читать, зато ото всех. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class BroadcastServer: virtual public ConnectBase&#60;TYPE&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public SocketUDP &nbsp;&#60;TYPE&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public SocketRead &#60;BroadcastReadRaw&#60;TYPE&#62;, TYPE&#62; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет коннекта для серверов. Умеет и читать и писать, ожидает от клиентов подключений. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketServerTCP: public SocketServer&#60;TYPE&#62;, public SocketWrite&#60;TYPE&#62;{};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Сокет коннекта для клиентов. Умеет и читать и писать, подключается к серверу как клиент. */</div><div class="code_line">template &#60;int TYPE&#62;</div><div class="code_line">class SocketClientTCP: public SocketClient&#60;TYPE&#62;, public SocketRead&#60;SocketReadRaw&#60;TYPE&#62;, TYPE&#62; &nbsp; &nbsp;{/*...*/};</div><div class="code_line">&nbsp;</div><div class="code_line">/* Контейнер сокетов для групповых опросов с таймаутом.</div><div class="code_line">&nbsp;&nbsp; Реализован через select() как единственный вариант реализации таймаутов. */</div><div class="code_line">class FDS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {/*...*/};</div></ol></div></div></div></div>Каждый из служебных классов решает ровно свою задачу. Каждый из пользовательских собирается из служебных как кирпичиков, и по факту пусты. (Ну почти, там конструирование кое-где перегружено для удобства.) Виртуальное наследование присутствует из-за совмещения атрибутов. При этом сами классы неполиморфны, т.к. позднее связывание там не нужно.<br>
Композиция в том виде, как она представляется в определении, ...смущает, скажем так. Слишком частное определение. Я могу себе представить композицию в виде атрибутов класса, но извне, т.е. на уровне интерфейса класса, это композицией не особо выглядит.<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">to be continued more</span>]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904682</guid>
        <pubDate>Thu, 23 May 2024 14:46:58 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904682</link>
        <description><![CDATA[Qraizer: Хм. Ну, GPT в целом тебя не обманул. Но есть нюанс: описал скорее следствия преимуществ и недостатков, нежели сами преимущества и недостатки.<ul class="tag-list"><li>Наследование не представляет собой средство повторного использования и уменьшения дублирования, для этого есть другие методы. Да, повторное использование и уменьшение дублирования имеет место, но это в целом лишь бонус. Наследование само по себе призвано решать другие задачи: декомпозиция сложной сущности на более простые и – при условии, что исходная сущность изначально была спроектирована из расчёта на это – расширение возможностей сущности.</li></ul>Важно не забывать, что наследование создаёт сильную зависимость нового класса от предков. Любые изменения в них отражаются на производном классе, т.к. они являются его частью. Это недостаток, ибо чем слабее связи между сущностями, тем проще управлять комплексом в целом, однако – гораздо реже, чем поначалу кажется студентам, впрочем – бывает так, что выгода с лихвой этот недостаток перебивает. Типичная ситуация использования: когда целью изначально был этот самый производный класс, и его деление на базовые оказалось просто удобным средством его декомпозиции на подобъекты. Ирония в том, что в таких случаях наследованию нет необходимости быть публичным, т.к. базовые классы не предназначаются для использования отдельно от производного и даже могут не иметь публичного интерфейса вовсе. Хороший пример – классы (не ассоциативных) контейнеров std::vector&lt;&gt;, std::deque&lt;&gt;, std::basic_string. Им всем нужен примерно одинаковый функционал по управлению своим хранилищем, который не привязан к свойствам конкретных объектов, которые эти контейнеры будут хранить. Нужно уметь проверять доступное место  в хранилище, нужно уметь его расширять/уменьшать, нужно уметь его перераспределять без потери уже имеющейся в нём информации. Почему бы не выделить этот функционал в отдельную сущность? Контейнеры его далее смогут просто использовать. Да, тут будет иметь место устранение дублирования и повторное использование, но даже притом, что если бы был только один тип контейнера, std::vector&lt;&gt;, например, то это всё равно выгодно, так как мы декомпозировали сложный объект на два простых, где каждый занимается своим делом и не лезет в дела другого. Ожин занимается хранилищем, другой push_back()чит, insert()ит, []сит итд. Так что я легко вижу тут некий std::storage, который приватно наследуется и std::vector&lt;&gt;, и std::deque&lt;&gt;, и std::basic_string. При этом std::storage запросто может оказаться без публичного интерфейса вовсе, т.к. бесполезен вне этих (ну или нами самописных подобных, мало ли) контейнеров.<br>
Второе свойство наследования – расширяемость – тоже студентами зачастую понимается превратно. Типа, у-у-у&#33; как здорово, у нас есть std::string, а давайте добавим ему связи с std::locale и научим case insensitive и up/down cases, и фигачат<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">template &#60;typename Ch, typename Tr = std::char_traits&#60;Ch&#62;, typename Al = std::allocator&#60;Ch&#62;&#62;</div><div class="code_line">class basic_locale_string: public std::basic_string&#60;Ch, Tr, Al&#62;, public std::locale;</div></ol></div></div></div></div>Увы, но так это не работает. Во-первых, std::basic_string&lt;&gt; не проектировался быть базовым для чего-либо, так что простое наследование вызовет кучу проблем для basic_locale_string, когда его пользователю понадобится в нём функционал обычного std::basic_string. Главное правило: если ваш производный класс не способен собою заменить базовый везде, где этот базовый ожидается, то наследование, как минимум публичное, не подходит. Расширение функционала среди прочего подразумевает, что прежний никуда не делся и может использоваться с нашим новым классом как будто он всё ещё старый. Просто потому, что вообще-то так и есть: производный класс полностью и без исключений включает в себя базовый. И если  вдруг в некую void foo(const std::string&amp;) передать наш locale_string, он обязан обеспечить этой foo() отработать с собой как с std::string. Внезапно выясняется, что это очень нелегко обеспечить, придётся чуть ли не на каждый чих городить прокси. Во-вторых, научить case insensitive и up/down cases – это здравая идея, но вот беда: тут сам locale_string решает, что оно нужно, и вот оно нужно всегда и точка. В итоге получается, что какие-нибудь find(), operator&lt;() и иже с ними будут работать не так, как с std::string. Т.е. мы не только расширили функционал, но и местами изменили. А вот это уже никуда не годится. Если мы хотим расширить, то это не подразумевает замену существующего, так что исходные find(), operator&lt;() итп нужно в locale_string оставить как есть, а для нового функционала завести новые методы. Ну и в итоге от наследования просто ничего не остаётся. Достаточно будет просто сделать новый namespace и нагрузить его дополнительным контентом, так что отдельного класса даже и вовсе не понадобится.<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">to be continued</span>]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904665</guid>
        <pubDate>Thu, 23 May 2024 12:24:25 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904665</link>
        <description><![CDATA[Majestio: На самом деле, мне интересны &quot;Преимущества и недостатки&quot;, т.е. способы применения. Когда что лучше, когда хуже, и почему. Чисто академический интерес.]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904604</guid>
        <pubDate>Wed, 22 May 2024 18:34:32 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904604</link>
        <description><![CDATA[Qraizer: <strong class='tag-b'>Majestio</strong>, так, вернулся, ещё раз перечитал, и у меня главный вопрос: ты чего хотел-то? Если учебник по терминам, то сорри, это ж азы, и вряд ли у тебя с этим проблемы. Если какое это отношение имеет к Плюсам, так ответ очевиден: прямое, т.к. Плюсы поддерживают парадигму ООП. Если как это в Плюсах реализуется, то это опять же учебник, только по языку, а не программированию.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904236</guid>
        <pubDate>Wed, 15 May 2024 14:38:46 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904236</link>
        <description><![CDATA[Majestio: Оставлю тут, из небольшой беседы с ChatGPT  :) <br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Наследование</strong></span><br>
<br>
Наследование в объектно-ориентированном программировании позволяет классу наследовать свойства и методы другого класса. Это позволяет создавать иерархии классов, где дочерние классы могут наследовать функциональность от родительских классов. Наследование способствует повторному использованию кода и уменьшению дублирования.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Композиция</strong></span><br>
<br>
Композиция представляет собой отношение между классами, где один класс включает в себя объект другого класса в качестве одного из своих полей. Это позволяет создавать более сложные объекты, используя уже существующие классы. Композиция способствует созданию более гибкой структуры программы и уменьшению связанности между классами.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Агрегация</strong></span><br>
<br>
Агрегация также представляет отношение между классами, где один класс содержит ссылку на другой класс в качестве одного из своих полей. Основное отличие от композиции заключается в том, что объекты, связанные агрегацией, могут существовать независимо друг от друга. Агрегация позволяет создавать более сложные объекты, оставляя возможность изменения и замены частей объекта.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Интерфейсы</strong></span><br>
<br>
Интерфейсы представляют собой контракты, определяющие методы, которые должны быть реализованы классами, которые реализуют эти интерфейсы. Использование интерфейсов позволяет создавать более гибкий и расширяемый код, так как классы могут реализовывать несколько интерфейсов, обеспечивая таким образом множественное наследование поведения.<br>
<br>
<strong class='tag-b'>Преимущества и недостатки</strong><br>
<ul class="tag-list"><li>Наследование обеспечивает повторное использование кода, но может привести к жесткой связанности между классами</li><li>Композиция и агрегация позволяют создавать более гибкие и модульные системы, но могут привести к увеличению сложности взаимодействия между объектами</li><li>Интерфейсы обеспечивают гибкость и расширяемость, но требуют более тщательного планирования и проектирования программы</li></ul>]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904061</guid>
        <pubDate>Sun, 12 May 2024 20:23:05 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904061</link>
        <description><![CDATA[Majestio: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=445466&view=findpost&p=3904059'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Qraizer &#064; <time class="tag-quote__quoted-time" datetime="2024-05-11T23:34:18+00:00">11.05.24, 23:34</time></span><div class='quote '>В смысле? Чё ты от меня хошь? Что мульён раз уже говорено? Я думал, счас кто-то что-то скажет, и у меня вдруг случится сдвиг мозга.</div></div><br>
Что-то я запамятовал, где такое обсуждалось. Ну а сказать, что кто-то скажет ... сложно, осталось совсем мало собеседников.]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904059</guid>
        <pubDate>Sat, 11 May 2024 23:34:18 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904059</link>
        <description><![CDATA[Qraizer: В смысле? Чё ты от меня хошь? Что мульён раз уже говорено? Я думал, счас кто-то что-то скажет, и у меня вдруг случится сдвиг мозга.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904057</guid>
        <pubDate>Sat, 11 May 2024 08:02:57 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904057</link>
        <description><![CDATA[Majestio: Вредина&#33;  :lol: Давай делись тайными знаниями&#33;  :lol:]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904056</guid>
        <pubDate>Fri, 10 May 2024 22:16:43 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904056</link>
        <description><![CDATA[Qraizer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=445466&view=findpost&p=3904055'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Majestio &#064; <time class="tag-quote__quoted-time" datetime="2024-05-10T19:22:52+00:00">10.05.24, 19:22</time></span><div class='quote '>а просьба показать и рассказать &quot;на пальцах&quot; сами-знаете-кому</div></div>Он с нескрываемым интересом послушает.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904055</guid>
        <pubDate>Fri, 10 May 2024 19:22:52 +0000</pubDate>
        <title>Наследование, Композиция, Интерфейсы ...</title>
        <link>https://forum.sources.ru/index.php?showtopic=445466&amp;view=findpost&amp;p=3904055</link>
        <description><![CDATA[Majestio: Всем привет&#33;<br>
<br>
В последнее время немного интересовался более другими языками, кроме как С++ и у каждого свои фишки по сабжу. Ну если более предметно, очень понравился <a class='tag-url' href='https://ru.wikipedia.org/wiki/Rust_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)' target='_blank'>Rust</a> и <a class='tag-url' href='https://ru.wikipedia.org/wiki/Dart' target='_blank'>Dart</a>. Второй наверное даже более интересен. Ну это так, типа &quot;взгляда ребёнка&quot;, которому показали коробочку с хэлоу ворлдами. Но&#33; Естественно, первое знакомство с этими ЯП волей-не-волей сформировало некий фидбэк к С++ и Perl, которые я очень уважаю. А еще я познакомился и выучил наизусть догмы из <a class='tag-url' href='https://majestio.info/articles/s.o.l.i.d-cpp.html' target='_blank'>S.O.L.I.D</a>, еще одно дополнительное измерение. В общем - в голове какая-то каша от всего этого. Ничего не понимаю - но очень интересно&#33;<br>
<br>
Хочется все эти знания-понятия как-то логически разложить по логическим полочкам в разрезе С++ возможностей. Вопросов куча, и скорее не &quot;как?&quot;, а &quot;для каких случаев лучше?&quot;.<br>
Понятное дело, что приветствие в начале поста было всем ... а просьба показать и рассказать &quot;на пальцах&quot; <a class='tag-url' href='https://forum.sources.ru/index.php?showuser=60764' target='_blank'>сами-знаете-кому</a>  :lol: <br>
<br>
Уверен, если оценить сабж с точки зрения описания темы - будет суперский материал для FAQ C++, ну и нам, недотепам - материал для утренних намазов.<br>
<br>
P.S. Всех страждущих прошу не скромничать&#33; Тема будет полезна всем.]]></description>
        <author>Majestio</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	