Здравствуйте, a7d3, Вы писали:
C0x>>А вот тут ты не прав. Есть ещё шаблоны и стат.программирование, ни с процедурами ни с ООП они ничего общего не имеют и дают совершенно интересные решения по сравнению с классическим ООП.
A>Это какая-то своя терминология от любителя изобретать свои паттерны? Чем не устраивает общепринятая?
Сложно сказать, что такое "стат.программирование", но вот шаблоны в C++ -- это обобщенное программирование (generic programming), еще одна парадигма, доступная в C++ наряду с процедурным подходом и ООП. И это общепринятая формулировка.
Здравствуйте, C0x, Вы писали:
...
C0x>Хм, спасибо, видал уже где-то такое, можно еще и лямбду в птр зафигачить при желании. Но как-то это страшно все потом выглядит. На лапшу похоже.
Когда всё четко уложено в сознании — не будет ощущения "лапши"!
Важно понимать, что smart-pointers основаны на принцыпе подсчёта ссылок на объект.
Когда счётчик ссылок уйдёт в ноль — то автоматически сработает деструктор объекта.
Здравствуйте, уважаемый velkin, Вы писали:
V>Умный указатель всего лишь решает проблему автоматического удаления объекта, когда на него больше никто не ссылается.
Так корректнее.
V>А конструктор и деструктор это методы, или как в C++ принято функции-члены.
Специализированные методы — так точнее.
V>В них можно поместить любую логику, или просто вызов функций отвечающих за эту логику.
Но обычно — в конструкторе то, что создаёт конкретный объект, в деструкторе — то, что конкретный объект уничтожает.
V>То есть new в случае указателей и умных указателей запустит один из конструкторов,
Да, но здесь потребуется вручную (в Вашем коде) указывать конкретный конструктор (у класса может быть несколько перегруженных конструкторов).
V>а delete запустит деструктор, но в случае с умными указателями последний может вызваться так сказать автоматически согласно запрограммированной логике.
Да, delete запустит деструктор — автоматически (без указания явного вызова delete в Вашем коде) при использовании smart-pointer (умного указателя).
V>Я уж забыл из какого это источника, но там говорилось что-то вроде того, что помните, конструктор и деструктор это методы (функции-члены).
Специализированные функции-члены.
Здравствуйте, C0x, Вы писали:
C0x>Я видел какие-то велосипеды с shared_ptr куда пихается лямбда функция с какой-то логикой, но это как-то помоему велосипедно слишком выглядит и не похоже на какой-то общий паттерн, который можно по всей либе юзать.
shared_ptr используется потому, что в С++ до сих пор нет готового класса для вызова кода по выходу из блока.
C0x>В простых случаях да, это поможет. Но если нужна сложная логика освобождения?
То вам придется писать сложный код в деструкторе. Не принципиально, будет это деструктор shared_ptr или ваш собственный. Но в любом случае непонятно, зачем вам в данной ситуации наследование.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Здравствуйте, C0x, Вы писали:
C0x>Привет,
C0x>давно не писал на плюсах, вот вернулся снова и понеслась душа в пляс
C0x>Надоели всякие Begin, End, Open, Close методы в программах. Хочу придерживаться принципа RAII.
Чем не RAII спрятать конструктор и вызывать его в статической функции, типа Create? Внутри все ресурсы резервируются, обёрнутые в try-catch. Она или правильный указатель будет возвращать, null или exception будет кидать в случае ошибки. Или на стеке тоже очень надо уметь инициализироваться?
А в конструкторе не надо исключения кидать. Это моветон.
Здравствуйте, C0x, Вы писали:
C0x>Смартпоинтер и RAII это одно и тоже?
Смартпойнтер — это воплощение идеи RAII. И речь не про конкретный условный unique_ptr, а в целом про концепцию объекта-владельца. Не нравится вам unique_ptr — всегда можно сделать к нему алиас, или написать свой, или взять готовый чужой — это чисто технический момент. Но все эти решения следуют одной концепции. Судя по тому, что вы возразили каждому, кто предлагал один из этих вариантов — вы отвергаете саму концепцию, а значит отвергаете и RAII.
C0x>Естественно, за любым костылем лежит целая история причинно-следственных связей. Ну вот к примеру взять Смартпоинтер. Любой программист на языке с GC скажет что это очевидно костыль, просто потому-что у вас ребята нет GC, но вы пытаетесь обойти этот недостаток пихая во все щели свои смартпоинтеры. Программист на Си++99 смотря на смартпоинтер скажет что это костыль, потому-что вы лентяи и не можете аккуратно писать код и следить за указателями и хэндлами.
Я и говорю — непонимание.
Особенно это:
C0x> пихая во все щели
А с пониманием станет ясно, что далеко не во все щели.
И продолжая вашу аналогию, программист на языке без GC должен считать наличие GC костылем (мол, чего это они сами не могут за ресурсами следить)? Это очень поверхностное суждение.
Любой язык с GC являет нам его составной частью своей концепции. То, что задумано изначально, не может быть костылем по определению.
RAII — был задуман изначально. Первые обобщенные реализации смартпойнтеров в открытом доступе появились уже в 90-м году.
И это было просто использование концепции и инструмента по назначению.
Здравствуйте, C0x, Вы писали:
C0x>То есть тебе не кажется странным использовать объект с именем unique_ptr для совершенно другой цели — выполнить логику удаления?
Вообще управления владением и доступом к имуществу. Это единственная семантика этого умного указателя == реализовать эксклюзивное владение.
Если твой большой объект владеет этим ресурсом (хэндлом, потоком и т. п.) эксклюзивно, то использовать std::unique_ptr -- прямой способ выразить это отношение на современном C++
Кстати, unique_ptr -- это не имя объекта, а часть имени типа объекта.
Из него не надо выводиться, сделай его полем с понятным именем, и будет просто и понятно.
C0x>Это я и называю костылями — использования не по назначению типов. Что касается врапперов над хэндлами все ок,пока логика — просто удалить хэндл,
А какое, по твоему, назначение std::unique_ptr ?
C0x>а если чуть сложнее то уже придется городить ещё кучу объектов непонятного назначения.
С этого места хотелось бы пример, что конкретно имеется в виду.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
C0x>>>А вот тут ты не прав. Есть ещё шаблоны и стат.программирование, ни с процедурами ни с ООП они ничего общего не имеют и дают совершенно интересные решения по сравнению с классическим ООП.
A>>Это какая-то своя терминология от любителя изобретать свои паттерны? Чем не устраивает общепринятая?
S>Сложно сказать, что такое "стат.программирование", но вот шаблоны в C++ -- это обобщенное программирование (generic programming), еще одна парадигма, доступная в C++ наряду с процедурным подходом и ООП. И это общепринятая формулировка.
Как будто обобщенное программирование является взаимоисключающим с процедурным и/или же ООП, таким же образом как и они между собой.
Для примера — модель акторов является взаимоисключащей с CSP? Вот так же и тут с обобщеным программированием.
Здравствуйте, a7d3, Вы писали:
A>Как будто обобщенное программирование является взаимоисключающим с процедурным и/или же ООП, таким же образом как и они между собой.
Вообще-то речь об этом:
A>И всего их две штуки — процедурная и ОО.
В С++, как минимум, три парадигмы из коробки: процедурное программирование, ООП и обобщенное. Хотя можно еще и про функциональщину говорить (скажем, в compile-time на шаблонах или на constexpr функциях), но это уже менее очевидно и может быть предметом спора.
Так что когда COx говорит о том, что парадигм в C++ не две, то он более прав, чем вы.
A>Для примера — модель акторов является взаимоисключащей с CSP?
Вообще-то да. Поскольку или-или. Т.е. либо вы кусок кода пишете на акторах одним способом, либо на CSP другим. И дополнять они могут друг-друга только если разные куски программы написаны по-разному.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
A>>Для примера — модель акторов является взаимоисключащей с CSP?
S>Вообще-то да. Поскольку или-или. Т.е. либо вы кусок кода пишете на акторах одним способом, либо на CSP другим. И дополнять они могут друг-друга только если разные куски программы написаны по-разному.
Именно, а выбирая обобщённое программирование человек может писать либо в рамках процедурного, либо в ООП.
Потому что нет выбора «обобщённое или ООП» как и нет выбора «обобщённое или процедурное».
Здравствуйте, a7d3, Вы писали:
A>Именно, а выбирая обобщённое программирование человек может писать либо в рамках процедурного, либо в ООП.
Вы заблуждаетесь.
A>Потому что нет выбора «обобщённое или ООП» как и нет выбора «обобщённое или процедурное».
Есть.
Попробуйте написать sort в каждой из этих трех парадигм и вы увидите, что вы вынуждены принимать разные проектные решения. Что будет выражаться на уровне даже интерфейса sort. Не говоря уже про детали реализации. И последствия. В частности, a) невозможность скрытия реализации шаблонных функций/классов в DLL/so, и b) ресурсоемкость компиляции обобщенного кода.
S>В С++, как минимум, три парадигмы из коробки: процедурное программирование, ООП и обобщенное. Хотя можно еще и про функциональщину говорить (скажем, в compile-time на шаблонах или на constexpr функциях), но это уже менее очевидно и может быть предметом спора.
Иван Чукич вполне обосновал Функциональное программирование на С++. С помощью чистых функций, как оно и требуется. И каррирование у него там есть, и монады. Ленивые вычисления тоже, но это еще раньше было понятно, до него.
Так что 4 парадигмы — однозначно.
И еще метапрограммирование на шаблонах, которое тоже функциональное.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, so5team, Вы писали:
S>Попробуйте написать sort в каждой из этих трех парадигм и вы увидите, что вы вынуждены принимать разные проектные решения. Что будет выражаться на уровне даже интерфейса sort. Не говоря уже про детали реализации. И последствия. В частности, a) невозможность скрытия реализации шаблонных функций/классов в DLL/so, и b) ресурсоемкость компиляции обобщенного кода.
Зачем в трёх? Почему не в четырёх?
Первое в процедурном с шаблонами (дженериками) и второе — ООП с шаблонами.
И ещё два — просто в процедурном и просто в ООП.
Само по себе обобщённое программирование не бывает, оно либо процедурное, либо на базе ООП.
Здравствуйте, a7d3, Вы писали:
S>>Попробуйте написать sort в каждой из этих трех парадигм и вы увидите, что вы вынуждены принимать разные проектные решения.
A>Зачем в трёх? Почему не в четырёх?
Потому что выше было сказано, что в C++ гарантированно поддерживаются три парадигмы. А по поводу четвертой можно спорить, есть ли поддержка ФП в C++ или нет: кто-то считает, что есть, кто-то -- что нет.
И вот в рамках трех парадигм (процедурная, объектная, обобщенная) у вас sort будет совершенно разный.
A>Само по себе обобщённое программирование не бывает, оно либо процедурное, либо на базе ООП.
Бывает. В Generic Programming функции и классы являются всего лишь строительными блоками, поэтому вам может казаться, что есть процедурное GP, и есть объектное GP.
Здравствуйте, so5team, Вы писали:
A>>Само по себе обобщённое программирование не бывает, оно либо процедурное, либо на базе ООП.
S>Бывает. В Generic Programming функции и классы являются всего лишь строительными блоками, поэтому вам может казаться, что есть процедурное GP, и есть объектное GP.
А почему не процедурное с шаблонами/дженериками и не ООП с шаблонами/дженериками?
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
S>>>Попробуйте написать sort в каждой из этих трех парадигм и вы увидите, что вы вынуждены принимать разные проектные решения.
A>>Зачем в трёх? Почему не в четырёх?
S>Потому что выше было сказано, что в C++ гарантированно поддерживаются три парадигмы. А по поводу четвертой можно спорить, есть ли поддержка ФП в C++ или нет: кто-то считает, что есть, кто-то -- что нет.
Бред был сказан и сейчас отсылка идёт к этому уже сказанному бреду.
Как одна из форм хамства и отказа аргументировать собственное мнение.
Говорят в деревнях с глубинками и на промышленных производствах до сих пор так принято общаться с коллегами и подчинёнными.
Здравствуйте, a7d3, Вы писали:
A>Говорят в деревнях с глубинками и на промышленных производствах до сих пор так принято общаться с коллегами и подчинёнными.
Да, мы народ простой. Чуть что, сразу конкретный пример. Ну а если этот пример столичной штучке с тонкой душевной организации не нравится, ну это не наши проблемы. Мы не огорчаемся от того, что ваше мнение оказывается бездоказательным.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
A>>Говорят в деревнях с глубинками и на промышленных производствах до сих пор так принято общаться с коллегами и подчинёнными.
S>Да, мы народ простой. Чуть что, сразу конкретный пример. Ну а если этот пример столичной штучке с тонкой душевной организации не нравится, ну это не наши проблемы. Мы не огорчаемся от того, что ваше мнение оказывается бездоказательным.
Конкретика где? Только бредовые утверждения на уровне псевдорелигиозных верований и попытки ссылаться на них.
Где пример того, насколько и чем конкретно обобщённое программирование на С++ отличается от ООП обыкновенного?
Такого плана, когда визави и содержимое STL знакомо, и SOLID & DI/IoC не чужды.
Для чего? Чтобы показать состоятельность и самостоятельность «обощённого программирования». Приводящую к необходимости выбирать между ним или процедурным или ООП.
В примере с sort. Разницу между процедурным и обобщенным программированием легко увидеть на cppreference (тыц раз, тыц два). Аналог sort-а на чистом ООП оставлю вам в качестве домашнего задания.
A>Где пример того, насколько и чем конкретно обобщённое программирование на С++ отличается от ООП обыкновенного?
А вы решите пример с sort-ом и сами увидите. Ну или можете посмотреть в сторону policy/trait-based подходов. В частности, почему в C++ для контейнеров аллокаторы или компараторы задаются посредством параметров шаблонов, а не через "ООП обыкновенный" с интерфейсами, наследованием и виртуальными методами.
Кроме того, обобщенное программирование в C++ вынуждено применять элементы из "типа ООП" потому, что в C++ даже struct -- это уже элемент ООП (так уж вышло, что между struct и class в С++ лишь косметические различия). И даже такие вещи, как tuple или sum types в C++ вынуждено выражаются через class. Тогда как будь в языке отдельное понятие для tuple и sum type (как, скажем, в Rust), то можно было бы увидеть и обобщенное программирование вообще без элементов ООП.
Как раз все это в сумме и позволяет говорить об Generic Programming как об отдельной парадигме.
A>Для чего? Чтобы показать состоятельность и самостоятельность «обощённого программирования». Приводящую к необходимости выбирать между ним или процедурным или ООП.
Выбор приходится делать. Причины излагались выше. И в этом посте, и выше по обсуждению.
Ну и на правах записного хама позволю себе ткнуть вас в _полное_ отсутствие каких-либо примеров с вашей стороны. Видимо, столичные штучки привыкли, что им верят на слово после употребления SOLID, DI, IoC и других страшных слов. В нашей деревне не прокатывает, звиняйте.