![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Отнюдь Программа В конечно, но тут речь шла не об этом. А речь шла о том, что на С++ невозможно реализовать проперти, использование которых синтаксически не отличается от использования полей классов/структур (или хотя бы просто переменных). Можно реализовать проперти, которые почти не отличаются, но полную замену получить нельзя (даже если не принимать во внимание код, который попытается получить указатель или ссылку на проперть) |
|||
|
||||
Lukkoye |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
Какие именно "огромные неудобства" ? Писать приходится меньше. Код проще. Приведенный вами код не рассматриваю, Когда вот такие ошибки лезут: source_file.cpp:5:30: error: ‘Property<T>::Property() [with T = std::basic_string<char>]’ is private class Property : public T { Property() { } Мне уже не хочется всерьёз рассматривать пример. |
|||
|
||||
Ihost |
|
||||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Да тема вышла действительно очень интересной, хотя по-прежнему совершенно непонятно, откуда стереотипные возражения против prorerty-свойтсв на языке C++ - да синтаксические средства языка значительно более выразительные, но это не повод отказываться от удобных getter/setter
Окей допустим определен UI-объект по аналогии как в .NET, в котором значительное число параметров с иерархической вложенностью; в таком случае есть два потенциальных варианта записи (Все имена классов- вымышленные, но поясняющие суть аналогии)
По мне такой вариант адекватен только на языке Java, где это сделано специально ради колоссального упрощения синтаксических структур языка, такой как невозможность перегрузки операторов и переопределения преобразования типов Да действительно, **полную** замену получить действительно невозможно, а для приближения к ней необходимо использовать вполне адекватный и удобный синтаксический сахар Можно вообще не использовать ни свойства, ни классы, а разрабатывать к примеру на языке ассемблера! Теперь давайте перейдем к совместимости: - Абсолютная 100% поддержка для Visual C++ и Borland C++ посредством конструкций __declspec и __property соответственно - Достаточно интересная поддержка для C++11 и старше посредством кода следующего образца Self-aware structs , в том числе для шаблонных функций, ссылок и константных выражений - 100% поддержка для набора инструментов вида Qt - Достаточная для удобной работы поддержка по образцу C++-кода, приведенного несколько сообщений назад При копировании на форум в том сообщении изчез спецификатор public, и если его вернуть, все заработает надлежащим образом; при добавлении определенной металогики подобную схему можно использовать и для фундаментальных типов, и для обычных классов - сейчас надо мануально указывать класс подлежащего типа Как итог можно сказать, что в C++ действительно нет property-свойств; впрочем с таким же успехом там не и методов классов, и даже переменных - при компиляции это невозможно вернуть обрано, в отличие от того же C#, который может полностью быть подвергнут обратной разработке Более того надо помнить, что C++ - язык достаточно низкоуровневый! Никто ведь не требует от той же функции printf, чтобы она сама определяла тип аргументов и их число - все знают что это невозможно, и подставляют мануальные аргументы С prorerty-свойствами ситуация несколько похожая- в случае их простой реализации, в некоторых достаточно сложных конструкциях потребуется операция explicit-приведения типов - но это ничуть не умаляет их удобства по сравнению с неудобными и громоздкими вызовами GetX/SetX Если кого-то не убедило и это, то можно вспомнить про вполне легальную синтаксически, но могущей привести к последующими проблемам времени исполнения конструкции
Присваиваемые левосторонние значения от функций, которые являются локальными переменными - не лучшая черта языка, но она есть Property-свойства же работают удобно и изяшно и не обладают почти никакими недостатками в общей атмосфере C++-кода Это сообщение отредактировал(а) Ihost - 19.11.2014, 14:13 |
||||
|
|||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Так если в приведённом стиле изобразить первый вариант, он получится не на много более грамоздким:
|
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
Примерно так и будет выглядеть
Это сообщение отредактировал(а) Dem_max - 20.11.2014, 19:26 -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Ihost |
|
||||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Хорошее решение, правда разве что
В одну строчку вряд ли получится записать, а если и получится - getter-ы будут вызываться дважды, и если в них осуществляется выполнение реальной функциональной нагрузки, то производительность снизится в 2 раза, в то время как в реальных property-элементах такого не возникнет |
||||
|
|||||
Lukkoye |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
Во-первых первый вариант не эквивалентен второму по логике работы. Потому что в первом варианте все промежуточные значения реализованы по значению. А значит hue += 10; увеличит внешнию копию, в то время, как во втором случае +=10 увеличит переменную-член класса. А во-вторых:
Таким образом, с точки зрения количества буковок, по факту первый вариант длиннее второго только на () и точечку. А теперь возвращаясь к нашим баранам. Если писать просто и не городить огороды с дураццкими промертями, то код будет не просто проще. Его будет меньше: 1. код классов проще. И по сложности кода и по количеству. потому что: 1.1 Вариант, когда вам не нужны сеттеры/геттеры, и вы делаете член public. Получаете точно такой же синтаксис, какой предоставляют проперти. Максимальную эффективноть и никакого геммороя (до тех пор, пока не понадобятся сеттеры/геттеры. Практика показывает - проблем не возникает). 1.2 Вариант, когда вам нужны сеттеры/геттеры, потому что нужно не просто предоставить доступ к данным, но и выполнить какую то дополнительную логику. Например, выполнить логгирование, или произвести валидацию, или испустить сигнал... В этом случае вам в любом случае понадобится функция-сеттер (ну или геттер). Только в простом случае вы пишите сеттер и больше ничего. В случае с проперти, пишите проперти, пишите сеттер, и потом навешиваете его на проперти. Тройная работа. Практического смысла в проперти нет никакого. С тем же успехом можно было бы просто реализовать сеттер. 2. на пользовательской стороне в наши дни уже давно никто не пишет полные имена методов или переменных. достаточно вбить первые две буквы, и ИДЕ подскажет полное имя. И в этом смысле совершенно не принципиально, что вбивать: имя переменной, или имя метода. Все равно используется автодополнение от ИДЕ. Поэтому с точки зрения использования ни public-переменные, ни простые сеттеры, ни проперти не имеют никакого выигрыша друг перед другом в плане скорости разработки. ----------------------------------------------------------------------------------------------------------- Ваш вариант ни разу не адекватный. Напротив - он бессмысленный, потому что не дает никакого профита, а только зазря усложняет код: Он не решает никаких проблем, с которыми не могли бы справиться обычные сеттеры. Он вообще не привносит ничего принципиального нового - это лишь бесполезный сахар, потому что с точки зрения функциональности он не привносит ровным счетом ничего такого, чего нельзя было бы реализовать с помощью обычного сеттера. Не ускоряет, а только замедляет разработку за счет увеличения времени на конструирования в классах-владельцев более сложный кода. Требует понимания и навыков работы с шаблонами. Шаблоны в бизнес-коде без какой бы то необходимости приводит к удорожанию разработки за счет более высокого порога вхождения разработчиков. ------------------------------------------------------------------------------------------------------------- Резюмируя: без всякой необходимости, совершенно напрасно усложнять себе жизнь? Это глупость. Техника оказалась не востребованной на плюсах, именно потому что бессмысленная. Это сообщение отредактировал(а) Lukkoye - 20.11.2014, 23:50 |
||||
|
|||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
[deleted]
Выше написано правильнее ![]() Я посчитал, что геттер возвращает по значению, но если по ссылке, то можно, конечно, сделать короче. Это сообщение отредактировал(а) NoviceF - 21.11.2014, 09:58 |
|||
|
||||
Ihost |
|
||||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Если сахар совсем не по душе, можно разрабатывать программы на чистом C или ассемблере - в первом случае минимум сахара + какая-никакая переносимость; кому-то может нравиться белый сахар, кому-то коричневый тростниковый - о вкусах вообще довольно бессмысленно спорить
Можно рассмотреть несколько аспектов: - Для обеспечения гибкости достаточно низкоуровневого C++ в нем был придуман синтаксических сахар в виде перегрузки операторов и implicit-конструкторов, благодаря которым те же вектора можно складывать по знаку плюс, или использовать красивые комплексные числа Если Вам все это не нравится, всегда можно использовать "не-сахарную" версию, но зачем, если можно сделать красивее и изящнее - Если в Вашей программе есть многочисленные формуло-подобные расчеты со множеством переменных классов, то код без property-свойств выглядит абсолютно нечитаемым, как то ball.SetSpeed(ball.SetSpeed().VectorSumm((canvas,GetSumForce().VectorDivide(ball.GetMass())).VectorMultiply(timespanner.GetTickPeriod()))) вместо адекватного математического ball.Speed += (canval.SumForce / ball.Mass)* timespanner.TickPeriod - Если в одном месте поменяется имя переменной, то придется менять все Getterы и Setterы, и даже в IDE автоматические замена вам не поможет, в то время как property-свойство - нормальный член класса и его можно отслеживать и переименовывать по всему проекту Никто не заставляет никого следовать определенным стилям в плане объема использования синтаксического сахара, более того как правила таковой сахар - большое зло, особенно в языках более высокого уровня К примеру, на дух не переношу бессмыслпенные сахарные залежи вроде Jquery или CoffeeScript - того же обычного EcmaScript хватает для любых целей за глаза Но в случае C++ property-свойства удобный и органичный механизм, такой же как и все остальные механизмы, основанные на перегрузке операторов Более того в случае с работы с UI-интерфейсом, доступ к свойствам часто осуществляется по их имени в сторковом эквивалентном трактовании, а немного улучшенная реализация property-свойств позволяет реализовать и это; по аналогичной причине по всех UI-шных версиях C++ - MSVC++, BorlandC++, Qt - в обязательном порядке есть языковая поддержка property-свойств |
||||
|
|||||
Lukkoye |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
В корне неверная мысль. Можно конечно посчитать, что сам по себе высокоуровневый язык - это сахар над машинными кодами. Но это неверно, потому что высокоуровневый язык отличается от машинных кодов парадигмой.
На языке си я могу реализовать объектно ориентированную архитектуру приложения. И это несмотря на то, что сам по себе язык из коробки ООП не умеет. Тем не менее реализовать можно, и существуют различные библиотеки, которые эту возможность используют. Например GTK: https://ru.wikipedia.org/wiki/GTK+ Однако, вы когда нибудь пробовали реализовать оо-архитектуру вручную? Что дает нам нативная поддержка ООП в с++ ? Вы очень ошибаетесь, если полагаете, что это "просто сахар". Это не просто сахар. Это действующая автоматика, благодаря которой, становится возможным , например, реализовать идеому RAII. На языке си можно имитировать ооп, то есть это всего лишь дешевая подделка. Никакой автоматики, все делается вручную. Плюсовый ооп - это не просто сахар. Это - технология, которая принципиально не доступна процедурному си. Я специально несколько раз делал акцент: проперти на языке с++ не дают ничего принципиально нового. Ничего такого, что вы не могли бы сделать при помощи обычных сеттеров/геттеров. Понимаете? ООП в с++ делает возможным вещи, которые принципиально не доступны процедурному си. А ваши проперти ничего такого принципиального нового не привносят. Таким образом ваше сравнение не корректное. Мухи отдельно, котлеты отдельно. Добавлено @ 23:01
Сама по себе технология, благодаря которой стало возможным перегружать функции - это не сахар. Это - технология. То о чем вы пишите - это следствия технологии в действии. И отличительная особенность заключается в простоте. Перегрузка функций столько же проста, как и просто создание функций. Грубо говоря, вам разрешили создавать функции с одинаковыми именами. Вы понимаете смысл? Вы не понимаете. Если бы вы понимали смысл, тогда вы бы поняли: изготовление пропертей, и эксплуатация приводит к усложнению кода. Использование перегруженных функций не приводят к усложнению кода. Если бы создать и использовать (и главное - это использовать) проперти было бы так же легко, как и обычные сеттеры-геттеры, тогда возможно проперти бы и прижились. Но они создают гемморой. Нахрена, если можно получить все тоже самое, только проще? Это сообщение отредактировал(а) Lukkoye - 22.11.2014, 23:06 |
||||
|
|||||
Lukkoye |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
И чем это отличается от:
? Или вас смущает, что в вашем первом варианте вы использовали более длинные имена, и похоже не осилили ссылочные типы с++ ? Так то фактическая длина имени не имеет значение. Автодополнение позволяет быстро вбивать имена любой длины. Значение имеет лишь читабельность. И что касается многочисленной формуло-подобной ботвы, то лично я предпочитаю формуло-подобный стиль код:
Может быть пример не очень удачный. Смысл в том, что "матиматическая формула" должна внешне быть похожей на математическую Поэтому, я часто делаю ссылки на длиные имена, и составляю формлулу из однобуквенных, так она действительно становится похожей на математическую. А поскольку длинные имена-оригиналы тут же, перед глазами, то никаких проблем с читабельностью не возникает. Добавлено @ 23:26
Не понял этого сообщения. Перефразируйте описания проблемы. Не удобный, и сильно ограниченный в возможностях костыль, который совершенно напрасно усложняет код, и создает проблемы. Это сообщение отредактировал(а) Lukkoye - 22.11.2014, 23:52 |
||||||||
|
|||||||||
Lukkoye |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
А что касается _г_о_в_н_о_кода на хабре, то я даже не стал рассматривать реализацию.
Я посмотрел только на использование (последний кусок кода, который содержит main). Просто сравните дизайн:
Вот так должен выглядеть приличный GUI на языке с++. Просто и понятно. Это сообщение отредактировал(а) Lukkoye - 22.11.2014, 23:47 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |