9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
|
||||||
1 | ||||||
Свойства класов - зачем помещать свойство в приват01.04.2012, 18:23. Показов 6039. Ответов 54
Метки нет (Все метки)
Очень часто встречал такие классы
PS. тут ещё мысля возникла, если в Си (не C++, а простой Си) небыло оператора new то получается небыло утечек памяти?
0
|
01.04.2012, 18:23 | |
Ответы с готовыми решениями:
54
Зачем свойство !hover в QSS Зачем нужно свойство @property (assign) Свойство column свойства margin Зачем всегда инкапсулировать переменные в свойства |
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
|
|
02.04.2012, 10:39 | 41 |
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.04.2012, 13:06 | 42 |
Там где-то в начале вопрошалось о косяках класса Vector3D. А вот они, степень важности от безразличной, до неработоспособности программы (сверху-вниз по файлу):
- Конструкторы не используют списки инициализации - Методы cross, dot должны быть константными. - Операторы +/- должны быть функциями, а не методами. Но в данном случае это не критично, т.к. нет преобразовывающего конструктора. - operator [] не работоспособен. Ты удивишься, но выравнивание на 4 байта уже стало большой редкостью. Данный метод в двух случаях из трёх вернёт мусор. - float * , то же, что и выше. - Большинство методов должны быть функциями в пространстве имён этого класса - Одни и те же операторы объявлены и как методы и как функции. Как-то так.
0
|
02.04.2012, 13:23 | 43 |
Да, да, понял, лоханулся с инициализацией. Признаю это. И так же признал бы необходимость в сокрытии всех полей классов, если бы увидел аргументы в пользу сокрытия.
Но пока что всё, к чему вы пришли это "для отладки". Я, как новичок, считаю, что лучше всего учиться на примерах. Но все примеры, которые я видел меня пока не убеждают. Ну, вот хотя бы этот ваш "контроль диапазона присваемого". Ну скажите, зачем мне ограничивать диапазон в классе Vector3D??? Что вообще может быть в сеттере вектора, кроме x=tx;y=ty... ? Прочитайте первый пост! Речь же шла именно о таких ситуациях, когда нечего написать в сеттере, кроме сеттинга! Или вот обругали тут этот класс за говнокод. Ну и что, но он же работает? В этом то и основной вопрос ТС. Зачем ораничиать самого себя в доступе (себя, а не мифических "других пользователей", которых во многих программах, особенно учебных и не существует). И не надо тут давить авторитетом "публикаций". ТС привёл конкретный пример геттера/сеттера, которые ничего не делают. Что мешает вместо этого сделать поле публичным? Покажите публикацию, которая требовала бы создавать такие пустые гетсеттеры. И опять заводите речь о "больших и сложных программах". Но как показывает практика, немалая часть программистов пихают прайват поля даже в простые программы. Или вы даже разрабатывая "Тетрис" завернёте все данные в приватные поля классов?
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.04.2012, 13:38 | 44 |
Именно так.
Именно так. Поэтому все переменные, которые не могут (не должны, но все мы люди) изменяться я делаю константными. Как и 90% всего кода - самодокументирование. Называя метод Get* и не делая его константным - ты врёшь самому себе. Создавая не константный метод, который не изменяет инвариант класса - ты врёшь себе. Создавая метод, который должен быть функцией, ты себе не врёшь, но помещаешь в интерфейс класса то, что не является частью его интерфейса, а это уже ошибка. Индусы с тобой согласны, да. У них тоже "всё работает". Добавлено через 1 минуту То, что является интерфейсом класса, должно быть в интерфейсе класса. То, что не является интрфейсом класса, должно не быть функцией в пространстве имён класса.
2
|
02.04.2012, 13:49 | 45 | ||||||||||
Ага, а разрабатывая "Тетрис" вы тоже завернёте в него 100500 приватных полей, "на всякий случай", "чтобы случайно всё не испортить". Вместо того, чтобы взять и забыть про ООП на время разработки простой программы.
Вопрос стоял о данных, которые вы объявляете приватными, но тут же открываете к ним доступ гетсеттерами. В чём отличие в применении
0
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||
02.04.2012, 14:13 | 46 | |||||
Kuzia domovenok, Хм. Ну. Желательно бы нечто вроде.
1
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.04.2012, 14:14 | 47 |
В том, что draw это часть интерфейса и должна быть методом. Более того, виртуальными могут быть только методы, а draw это именно виртуальный метод (то, что у тебя не виртуальный, это упущение при проектировании, ты бы исправил эту ошибку чуть позже).
Ты не открываешь к ним доступ. Там выше где-то был пример с полями a,b,c и методами доступа гарантировалось, что с равно сумме a и b. Так это ошибка проектирования. Поле с там вообще не нужно, т.к. оно вычисляется из a и b. Т.е., когда разработчик обнаружит эту ошибку, он просто удалит поле с и исправит реализацию пары методов и ему не придётся изменять 100500 вызовов этих методов. А что бы пришлось делать, если бы непосредственно обращение происходило к полю с? Как использовать переменную, которой больше нет? Пришлось бы везде писать a+b или вводить таки новую функцию. А теперь представь, что это всё происходит в dll, которой пользуется куча народа. Сколько матерных слов ты услышишь в свой адрес из-за того, что им придётся рефакторить все свои приложения? В первом посте ТС нтерфейс класса ошибочен. Начиная с не виртуального деструктора и заканчивая методом set* для изменения счётчика.
1
|
Модератор
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
|
|
02.04.2012, 14:36 | 48 |
Точно все посты читаете? silent_1991 в 37 посте привёл очень даже жизненный пример, как соблюдение простого негласного правила и написание пары "лишних" строчек кода может спасти от внесения правок везде, где использовалась свежеизменённая часть класса.
Можно проехать метров 50 за рулём автомобиля с закрытыми глазами и при определённом везении никого не покалечить. Но если зажмуриваться во время вождения более-менее регулярно, обязательно станешь героем увлекательного квеста с участием ГИБДД, МСЧ, etc... (опять же, если повезёт)... Попытки "давить авторитетом", если не ошибаюсь, начались со ссылки на абы как написанный класс вектора в трёхмерном пространстве.
1
|
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
02.04.2012, 14:59 | 49 |
Я?? Где? О_о
О чём же вы тогда можете спорить? После этих слов вас сложно воспринимать всерьёз. Вас не возьмут работать в гугл. Да как же вы не поймёте, основная причина, по которой появилось ООП - повторное использование кода не через копипаст. Я, например, писал как-то на втором курсе один класс чисто для себя, не предполагая его никому показывать. Если бы я там наговнокодил, так бы он и валялся в папочке со старыми проектами. Но я старался сделать всё по фэншую. И что теперь? После минимального рефакторинга (по сути переписывание некоторых мест под новый стандарт) я вставил его в диплом. Вот вам и учебная программа. Профессиональный программист не разделяет программы на "трукод для всеобщего обозрения" и "говнокод для себя". Оу-оу, от кого я это слышу? Естественно. Погуглите "принцип наименьших привилегий". Добавлено через 2 минуты Я это называю нажать педаль газа вместо тормоза. Тут уж никто не гарантирует программиста от его собственной тупости.
2
|
8384 / 3616 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
|
|
02.04.2012, 15:02 | 50 |
Использование ацессоров для отладки - это огромное преимущество, но не только для этого они нужны. Простой пример из реального проекта. Представьте, что у вас есть класс и вам нужен триггер на изменение какого-то из полей. Что вы будете делать? Будете выворачивать свой класс наизнанку и каждый раз заново расписывать аналог триггера или же просто в сеттере вызовите нужный обработчик? Еще один пример - у вас есть некая ентити. У вас есть некая мапа ченджей данных в этой энтити. Как вы будете отлавливать изменение? А я просто добавлю в сеттере код, который будет отображать изменение данных в мапе.
да ладно тебе. Все так учатся. Сначала "лишь бы класс работал", потом "лишь бы выполнял поставленную задачу", позже "как бы эффективнее выполнял задачу", а только потом "как сделать так, чтобы он эффективно выполнял задачу и был масштабируемым". У него все еще впереди
0
|
silent_1991
|
02.04.2012, 15:09
#51
|
Не по теме: M128K145, когда человек учится, он не рассуждает о высоких материях. Это то же самое, как если бы я сказал своей первой учительнице, что "чк" и "чн" пишется с мягким знаком потому, что мой друг-гопник их так пишет.
0
|
fasked
|
02.04.2012, 15:27
#52
|
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.04.2012, 15:29 | 53 |
0
|
02.04.2012, 18:40 | 54 |
[QUOTE]IDrawer::draw(const std::shared_ptr<Shape>& shape);[QUOTE]
Ой, вот только не надо этих извращений. Мы на первых страницах определились, что программа пишется в одиночку, и не претендует на звание "универсальногововсесторонырасширяемого движка". Смысл тогда плодить в ней сущности? Давай не будем о них, об интерфейсах и виртуальности. просто потому что нигде не сказано, что у меня класс Shape абстрактный и взят из известного Страуструпповского примера. Может я имел в виду вполне конкретный Шейп? Но мне всё равно кажется, что такие механизмы, как использование триггеров, планируются до того, как мы решили создавать этот класс.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
02.04.2012, 18:57 | 55 |
Сообщение было отмечено как решение
Решение
Мне стыдно, но я не читал Страуструпа и не знаю, о каком примере идёт речь. Но класс Shape не может быть конкретным по определению, т.к. с таким названием он может быть только базовым. Отсюда и все следствия.
Где ты взял сложность? Это просто альтернативный подход. Если метод Draw не является интерфейсом данного класса, то он может быть частью интерфейса другого объекта, который умеет рисовать объекты заданных типов. Никакой сложности и мегауниверсальности, просто иной взгляд на проблему. Тогда ты "очень плохой программист", если такие названия классам даёшь. Особенно в ООП, да. И о чисто виртуальных я слова не говорил. Я там подробно описал. Если с сложновычисляемая производная, то она кэшируется. При этом кэш не определяет инвариант. А ты чувствуешь разницу между "нажать F7" и "провести рефакторинг кода, заменить обращения к переменной с на вызов метода и нажать F7"? Привычка вырабатывается за 21 день (это из курса психологии). Потом делать начинаешь не задумываясь. Если при обучении будешь делать абы-как, рисуя всякую непотребщину изо-дня в день, то ты привыкнешь так писать и будешь писать так всегда. Переучить толстолобика практически невозможно (требуется уже больше 21 дня). Поэтому делать ПРАВИЛЬНО нужно сразу же, начиная с Хеллоу Ворлда. А я писал, поэтому поверь на слово. Я вот щяс рефакторил програмульку... Всего полторы тысячи файлов... Знаешь... много времени исправление таких "мелочей" занимает. Очень много.
3
|
02.04.2012, 18:57 | |
02.04.2012, 18:57 | |
Помогаю со студенческими работами здесь
55
Зачем нужны автоматически реализуемые свойства? Зачем нужны автоматические свойства? {get; set} Зачем использовать поля, если есть свойства? Как назначить свойства блоку div через свойство SetAttribute? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |