Здравствуйте, MaximE, Вы писали:
ME>Шахтер wrote:
>> ME>Вот здесь разжевано, чем плохи свойства: C++ Properties -- a Library Solution >> >> Нет ни одного аргумента. Только ссылка на мнение неких безымянных "экспертов".
ME>Лично для меня мнение эксперта — аргумент.
Ладно, не будем об экспертах. Мы и сами тут все с усами.
ME>Вообще, я не вижу как property могут сделать мой код более элегантным, понятным, кратким и эффективным.
ME>-- ME>Maxim Yegorushkin
А так?
class Vect
{
int *vect;
size_t vect_size;
public:
size_t size { get { return vect_size; } }
int * begin { get { return vect; } }
int * end { get { return vect+vect_size; } }
};
Не знаю. Если я пишу на C#, то я нахожу свойства и удобными, и полезными. Не вижу, что мешает включить их в С++.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, rancorous, Вы писали:
R>>Почитал я тут дискуссию по поводу "Свойств" на С++ и вот что скажу — для С++ затея плохо реализуемая. WH>А еще придется вводить новое ключевое слово, еще придется вводить новый встроеный тип "указатель на свойство"... WH>И еще что касается геттеров/сеттеров то не забываем что в С++ есть перегрузка функций WH>
J>>a.x++;//вот читаю я код и задаюсь вопросом - это открытое поле класса или свойство
J>>
f(x);//вот читаю я код и задаюсь вопросом - это функция, или указатель на функцию, или функтор?
//И у него(нее) один параметр? Или пять, из которых 4 по умолчанию?
//А может, это вообще шаблон неизвестно чего, инстанцированный неизвестно чем?
//А может, это объявление переменной х типа f, где f - это неизвестно где затерявшийся typedef?
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>По-моему, пользоваться std::sort и std::string проще, чем qsort и char*. С приходом std возможностей стало меньше? WH>Не стоит путать core language и билиотеку.
Сорри, не совсем понял, о чем ты.
qsort и куча функций strxxxx для работы с char* — это же библиотека.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Glоbus, Вы писали:
J>>>
J>>>a.x++;//вот читаю я код и задаюсь вопросом - это открытое поле класса или свойство
J>J>>
J>
J>f(x);//вот читаю я код и задаюсь вопросом - это функция, или указатель на функцию, или функтор?
J> //И у него(нее) один параметр? Или пять, из которых 4 по умолчанию?
J> //А может, это вообще шаблон неизвестно чего, инстанцированный неизвестно чем?
J> //А может, это объявление переменной х типа f, где f - это неизвестно где затерявшийся typedef?
J>
вишь как ты все правильно подметил . так зачем еще неоднозначности добавлять
Удачи тебе, браток!
Re[7]: Свойства в С++
От:
Аноним
Дата:
15.07.04 07:45
Оценка:
А>>Ну а что мешает возвратить из метода get ссылку на переременную-член класса? J>То, что по этой ссылке переменная будет изменена, а объект об этом ни сном, ни духом
Ну вот для этого и придумали ООП. Чтобы все изменения состояния объекта делались в одном месте — методе данного объекта. Тогда не нужно будет мучительно искать по коду в 100 тысяч строк где устанавливается неверная величина. Использование переменной-члена класса в выражениях плохой стиль с этим ведь ты спорить не будешь? Значит, использование свойств, поощряющее подобный стиль программирования, также является плохим стилем, ведущим к ошибкам в программе.
Re[7]: Свойства в С++
От:
Аноним
Дата:
15.07.04 07:53
Оценка:
Здравствуйте, _nn_, Вы писали:
__>А как отслеживать изменения ? __>
__>class X
__>{
__>int x;
__>public:
__>int& get_x() { return x; }
__>};
__>X a;
__>a.get_x()=3; // как узнаем что x изменился ?
__>
Легко завести промежуточный объект с перегруженными операциями, в которых и будет проверятся корректность изменения значения переменной и возвращать его. Этот способ имеет еще и то преимущество, что будут перегружены только те операции, которые с переменной-членом планируется произвести. Но, все это — следствие неверного подхода. Принцип ООП: состояние объекта можно менять только через методы данного объекта иначе мы снова скатываемся к процедурному программированию, что для больших программ приводит к большим же проблемам, чтобы избежать их и был ООП придуман.
Здравствуйте, Glоbus, Вы писали:
G>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Glоbus, Вы писали:
J>>>>
J>>>>a.x++;//вот читаю я код и задаюсь вопросом - это открытое поле класса или свойство
J>> J>>>>
J>>
J>>f(x);//вот читаю я код и задаюсь вопросом - это функция, или указатель на функцию, или функтор?
J>> //И у него(нее) один параметр? Или пять, из которых 4 по умолчанию?
J>> //А может, это вообще шаблон неизвестно чего, инстанцированный неизвестно чем?
J>> //А может, это объявление переменной х типа f, где f - это неизвестно где затерявшийся typedef?
J>>
G>вишь как ты все правильно подметил :)) . так зачем еще неоднозначности добавлять
потому что лишняя маленькая неоднозначность на фоне огромного количества имеющихся никакой погоды не сделает :)
Главное в данном случае — естественный синтаксис, как в случае со скобками, когда не важно, с чем ты работаешь — с функцией или функтором и т.п., так и в случае с операцией доступа к полю (точка или стрелка), когда не важно, обращаешься ты к обычному полю или к свойству.
Если свойства ввести в язык, то это можно сделать корректно и гибко, в отличие от любой библиотечной реализации.
А это приятное свойство синтаксической идентичности с прямым доступом к члену очень играет на руку при написании шаблонов.
Твое "вот читаю я код и задаюсь вопросом" непосредственно приложимо к шаблонам в стиле той же STL с их использованием предикатов, куда можно засунуть как обычную функцию, так и функтор с какой угодно сложной логикой.
Опять же, как видишь, тут на форуме народ постоянно задается вопросом, что же такое iterator у vector или string — указатель или какой-то класс с хитрым поведением. В этом, конечно, есть определенная проблема, но это — плата за гибкость.
Или когда ты видишь запись типа a->x, ты ведь не можешь сказать, что такое а — указатель или класс с переопределенным operator->.
Важно, что код, который выглядит осмысленно, делает то, что написано, а как он это делает — через использование сотни промежуточных классов или напрямую — это уже не важно.
В этом — суть обобщенного программирования.
А настоящая мощь шаблонов, позволяющая им быть инструментов действительно обобщенного программирования, проявляется как раз при использовании подобного "синтаксического сахара" типа свойств, переопределенных операторов, автоматических разворачиваний цепочек вызовов operator->, автоматического выведения параметров шаблонных функций из типов аргуметов, и т.д. и т.п.
А>>>Ну а что мешает возвратить из метода get ссылку на переременную-член класса? J>>То, что по этой ссылке переменная будет изменена, а объект об этом ни сном, ни духом
А>Ну вот для этого и придумали ООП. Чтобы все изменения состояния объекта делались в одном месте — методе данного объекта. Тогда не нужно будет мучительно искать по коду в 100 тысяч строк где устанавливается неверная величина.
Со свойствами таких проблем не возникнет — у тебя ведь есть функция-сеттер. Поставь точку останова в нее и наслаждайся :)
A>Использование переменной-члена класса в выражениях плохой стиль с этим ведь ты спорить не будешь?
Буду :)
ООП — не священная корова. Все средства хороши к месту.
У меня нет никакого желания превращать свои программы в "огромное количество идиотских круглых скобок" :)
я считаю, что
a.x = b.x*(c.y + d.y);
выглядит гораздо лучше, чем
a.set_x(b.get_x()*(c.get_y() + d.get_y()));
A>Значит, использование свойств, поощряющее подобный стиль программирования, также является плохим стилем, ведущим к ошибкам в программе.
Если не секрет, зачем может понадобится производить такие манипуляции с членами класса? Если необходимо каким-то сложным образом изменить состояние объекта, то для этого вполне подойдет специальная функция-член объекта. ООП и был придуман затем чтобы избежать таких вот конструкций, которые, при раздувании кода, вызывают различные side-эффекты. То, что написано, не является написанием кода в стиле ООП, а известный процедурный стиль программирования. Конечно, программировать можно и, в некоторых случаях, необходимо, и с помощью этого стиля, но тогда зачем вообще классы использовать? Можно просто объявить четыре переменных a, b, c и d и дальше оперировать с ними подобным образом. Я не считаю ООП священной коровой, но, если используются понятие класс, то надо использовать парадигмы написания кода, соответствующие этому онятию. Т.е. если сказал А, надо говорить Б. Я не буду говорить здесь о том, что такой код нехорош уже тем, что непонятно зачем такое преобразование вообще делается. Неужели не проще и яснее завести метод типа CalcPolinom где произвести те же манипуляции?
Конечно, каждый человек имеет право на свое мнение и свою программу может писать в таком стиле как ему удобно, пусть если удобство это достигается путем проникновения через задний проход, но в промышленность такой код конечно, никто не допустит, да и вообще не ясно, дойдет ли программа, написанная таким стилем, до конечного пользователя.
Re[5]: Свойства в С++
От:
Аноним
Дата:
15.07.04 09:24
Оценка:
J>>>
J>>>a.x++;//вот читаю я код и задаюсь вопросом - это открытое поле класса или свойство
J>J>>
J>
J>f(x);//вот читаю я код и задаюсь вопросом - это функция, или указатель на функцию, или функтор?
J> //И у него(нее) один параметр? Или пять, из которых 4 по умолчанию?
J> //А может, это вообще шаблон неизвестно чего, инстанцированный неизвестно чем?
J> //А может, это объявление переменной х типа f, где f - это неизвестно где затерявшийся typedef?
J>
Ну зачем же так сразу f(x)? не лучше ли назвать этот метод Increment_x и убрать все эти проблемы с неоднозначностью? А что такое Increment_x, шаблон или неизвестно чего, проще всего выяснить по его типу, как это компилятор делает. Если же в данном методе хочется еще и избежать проблем с параметрами по умолчанию, то выход прост как все гениальное: не ставь эти параметры! В данной случае вообще параметров не нужно что есть хорошо, как сказал Создатель на шестой день творения. Не надо усложнять вещи там где нет в этом необходимости. На языке си++это звучит как: не плоди объекты без нужды .
J>>a.x = b.x*(c.y + d.y);
А>Если не секрет, зачем может понадобится производить такие манипуляции с членами класса? Если необходимо каким-то сложным образом изменить состояние объекта, то для этого вполне подойдет специальная функция-член объекта. ООП и был придуман затем чтобы избежать таких вот конструкций, которые, при раздувании кода, вызывают различные side-эффекты. То, что написано, не является написанием кода в стиле ООП, а известный процедурный стиль программирования. Конечно, программировать можно и, в некоторых случаях, необходимо, и с помощью этого стиля, но тогда зачем вообще классы использовать? Можно просто объявить четыре переменных a, b, c и d и дальше оперировать с ними подобным образом. Я не считаю ООП священной коровой, но, если используются понятие класс, то надо использовать парадигмы написания кода, соответствующие этому онятию. Т.е. если сказал А, надо говорить Б. Я не буду говорить здесь о том, что такой код нехорош уже тем, что непонятно зачем такое преобразование вообще делается. Неужели не проще и яснее завести метод типа CalcPolinom где произвести те же манипуляции?
А>Конечно, каждый человек имеет право на свое мнение и свою программу может писать в таком стиле как ему удобно, пусть если удобство это достигается путем проникновения через задний проход, но в промышленность такой код конечно, никто не допустит, да и вообще не ясно, дойдет ли программа, написанная таким стилем, до конечного пользователя.
Если честно, не вижу тут заднепроходных способов, скорее, таковым я склонен считать лозунг "все через геттеры/сеттеры" (в общем-то, как и любой другой лозунг). Потому что все средства хороши к месту.
В конце концов, очень многие парадигмы не дружат друг с другом, например, спецификации исключений и наследование. Или они же и шаблоны.
А другие парадигмы — очень даже дружат, например, ООП и структурное программирование.
Потому что ООП — это то, как общаются объекты и классы между собой, а внутри этих классов — старое доброе СП, хоть и сдобренное всякими наследованиями и прочими виртуальностями.
Почему, если я написал слово class, я немедленно должен все делать синтаксически через геттеры-сеттеры?
9/10 кода, использующего геттеры и сеттеры, используют их тривиальные реализации, которые абсолютно ничем не отличаются от прямого доступа к члену класса, за исключением очень большого неудобства использования.
И я считаю естественным желание людей писать простой и понятный код, который будет выглядеть так, как он должен выглядеть.
И если есть средство успокоить и наших, и ваших, предоставив естественный синтаксис, упрятав при этом под ним вызовы геттеров-сеттеров — я обеими руками за это средство.
P.S. Раз уж мы коснулись этой темы, смею уверить, мои программы доходили до конечного пользователя, и эти пользователи оставались очень довольными как кодом, так и работой программы.
You will always get what you always got
If you always do what you always did
Re[11]: Свойства в С++
От:
Аноним
Дата:
15.07.04 10:33
Оценка:
J>Если честно, не вижу тут заднепроходных способов, скорее, таковым я склонен считать лозунг "все через геттеры/сеттеры" (в общем-то, как и любой другой лозунг). Потому что все средства хороши к месту.
Таковой лозунг я не декларировал. Я говорил о принципе ООП: состояние объекта должно меняться ТОЛЬКО в методах самого объекта. Этот простой принцип был придуман не просто так, а после длинных бессонных ночей перед выпуском програмных продуктов, когда, в программе из более чем 100 тысяч строк, что-то не работает и непонятно прежде всего ГДЕ произошло нежелательное изменение состояния программы. Следуя же принципу выше очень просто решить первую задачу исправления дефекта программы: локализацию ошибки. Ради этого, в общем, все и было задумано.
Не хотел никого оскорбить и обидеть когда писал про заднепроходный стиль, но неужели ты всерьез полагаешь, что все эти горы документации по стилю, люди, которые специально нанимаются для того, чтобы контролировать стиль написания и черт знает еще какая уйма денег которая тратится, все это было сделано просто так, ради любви к красоте? Мне кажется, совсем наооборот; люди были к этому вынуждены. Я понимаю, что это не аргумент, как вообще оценка человечеством каких-то идей для многих людей не является аргументом, но таки стоит задуматься, что может все это не зря делается раз столько людей этим занимается?
Вообще, путь отрицания авторитетов ведет прямо в маргинальную группу. Есть маргиналы физики, ученые, которые не признают например, теории относительности Эйнштейна, есть просто маргиналы — люди, не признающие правил, установленных в социуме, в котором они проживают, а есть маргиналы — программисты, не признающие очевидных истин, опыта, выработанного человечеством за 40 лет существования данного вида деятельности.
В общем, спорить здесь бесполезно, все аргументы были высказаны и не услышаны, но все таки, прислушиваться к чужому мнению хоть иногда, но следует.
Спасибо за лекцию, конечно :)
Только она не имеет никакого отношения к свойствам, ибо свойства работают через геттеры и сеттеры, и никто не мешает поставить точку останова или отладочную печать в сеттер и проследить, где что изменилось.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
WH>Блин как все просто у тебя получается... тогда напиши спецификацию свойств, а мы посмотрим так ли это просто как тебе кажется.
простым должно быть использование свойств, а реализация — уж как получится.
если честно, я бы рад внести свой вклад :) да времени нет.
Да и не уверен я, что свойства корректно реализуемы в полном объеме (т.е. с поддержкой указателей на свойства и т.п.)
J>>>По-моему, пользоваться std::sort и std::string проще, чем qsort и char*. С приходом std J>>>возможностей стало меньше?
WH>>Не стоит путать core language и билиотеку.
j> Сорри, не совсем понял, о чем ты. j> qsort и куча функций strxxxx для работы с char* — это же библиотека.
А проперти пойдут в core language, вот в этом и разница.