![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
с его данными тоже никто работать не собирается. Никто не должен предусматривать все способы. Пиши те способы, которые нужны на данный момент. Если потребуется новый способ, ты напишешь новый класс, наследник Write реализуя интерфейс нужным тебе способом и все. С работавшим до этого кодом ничего делать не нужно. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
||||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну да, конечно. Но это ведь данные этого класса(наследника Write) и нигде кроме самого класса они не используются. А... Я понял о чем вы. В том смысле, что данные Write используются в его наследнике? Так это все из тойже оперы. Классы не должны наследовать данные (бывают конечно исключения но это исключения). Ведь я стою на принципе, что данные не интересуют никого вне класса в том числе и наследников. Почему тогда они наследуются? Если они не интересуют никого Я уже писал выше, плохо когда детали реализации становятся частью интерфейса между родителем и наследником |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
что то я запутался: где у тебя храняться данные, которые надо вывести на печать или на экран?
в потомке Write или где-то еще? |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
по моему очень простой пример. Функция write получает данные в аргументе от MyClass и куда-то их записывает. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Еще раз повторю свой вопрос: как метод write получит доступ к SomeData.
В данном случае это принципиально, поскольку класс Write и его наследники не имеют своих данных, а служат лишь для обработки данных, полученных извне. Если SomeData это простая структура, то тогда причем тут полиморфизм, обращаемся напрямую к полям этой структуры и выводим все на печать. Если структура SomeData изменится, придется переписывать много кода. Если же доступ к SomeData идет через get/set, то есть надежда, что придется переписать только эти методы. Кстати, в данном первом примере вполне можно было обойтись без полиморфизма: просто наделать функции типа writeToFile, writeToPrinter и т.д. Как же тогда получить доступ к данным SetData без get/set и без нарушения инкапсуляции? |
|||
|
||||
| Fazil6 |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
еще раз повтаряю
Добавлено @ 23:02
ничего не понял. |
||||
|
|||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Цель этого примера была конкретная: показать, что можно обойтись без меода get(). Я просто пытаюсь понять, действительно ли это так в данном "абстрактном" случае. Возможно, мы просто говорим о разных вещах. |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
там разве где-нибудь есть такой или подобный метод? |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Fazil6, похоже мы и вправду говорим о разных вещах.
|
|||
|
||||
| UnrealMan |
|
||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Нет, это не совсем то же самое.
А если эти данные нужны в обоих классах (BaseClass и DerivedClass) и они используются несколькими общими методами? Предлагаешь продублировать все эти данные и связанные с их обработкой методы?
Но интерфейс-то не открытый, а защищённый. А терять в общности, которую мы могли бы выразить с помощью защищённых данных и применённых к ним методов, – это хорошо? Эт я просто намекаю на то, что SomeData – это скорее некий универсальный тип, предназначенный для передачи данных в методы вывода, нежели тип поля класса (часто ли нужно выводить именно значение какого-то одного поля?). Т.е. метод output в MyClass должен преобразовывать члены-данные в данные вывода, которые дальше отправляются куда надо. Но тогда зачем вся эта возня с наследованием?
Укажи мне на какое-нибудь преимущество твоего способа перед тем, который только что продемонстрировал я. Забота о времени жизни каких-то левых вспомогательных объектов. Это сообщение отредактировал(а) UnrealMan - 13.7.2006, 12:02 |
||||||||||
|
|||||||||||
| Fazil6 |
|
||||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
UnrealMan,
из этого примера вообще непонятно, зачем нужен наследник. Я вам говорю, что методы get и set, наследование данных как правило свидетельствуют о плохом дизайне. Почти всегда можно сделать по настоящему ОО классы и на самом деле текста будет меньше и модель будет гибче и в сопровождении будет проще. А вы мне что отвечаете? "Нет! Доступ к данным необходим! Без него вот этот пример (здесь идет пример) не работает!" так я повторю - неправильный дизайн. Вот этот твой пример ничего не доказывает. Я вообще из него не вижу никаких резонов иметь родителя и наледника. Включи Method3 в родителя и все.
что значит зачем? код один и тот-же, но используется в зависимости от действительного типа аргумента. У меня для вывода может использоваться одна единственная (невиртуальная, неперегруженная, никак не переопределенная функция), а результат я буду получать в ней совершенно разный в зависимости от типа аргумента переданного в нее. Вот зачем наследование и полиморфизм. Теперь по поводу твоего последнего примера. Ржунимагу.
никакого. Ты написал абсолютно тоже самое, что писал я. Я могу конечно начать придираться к реализации (а есть к чему у тебя придираться и даже очень, особенно после Забота о времени жизни каких-то левых вспомогательных объектов. ), но сейчас мы говорим о другом. есть класс UserClass, у него есть данные. Но ведь у него нет методов get/set и ничего похожего на них. Вывод данных осуществляет сам класс UserClass, он решает что выводить. Где в твоем примере кому-то потребовались данные от UserClass? Все нормально. writer - это таже самая виртуальная функция по сути. Просто виртуальность ее ты сам обеспечиваешь. Ну пожалуста. А вот это
я вообще не замечаю. Если вокруг переменной нарисовать фигурные скобки и написать слово class, то классом эта конструкция не станет. Это в данном примере не класс, а структура данных, и как я писал выше тут смысл в самих данных и доступ к ним какбы очевидно должен быть, иначе что это за данные, которые я не могу видеть. Это тоже самое, что и SomeData в моем примере и если вас так сильно сбило всех с толку это слово то я уже писал, считайте это int или string или как хотите |
||||||||||
|
|||||||||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Ладно, приведу пример поконкретней. Пусть у нас имеется игра. В ней есть два вида персонажей: игрок (управляется пользователем) и монстр (управляется программно – простеньким искусственным интеллектом). Каждый персонаж обладает следующим набором свойств: положение в пространстве Pos, запас здоровья Health, запас брони Armor. Каждому персонажу можно нанести повреждение (Damage), проверить, не мёртвый ли он (IsDead), а также переместить в пространстве (Move) (каким образом – зависит от вида персонажа). Помимо этого, игрок обладает неким ограниченным количеством боеприпасов WeaponAmmo, а также может подымать аптечки (PickUpHealthPack) и броню (PickUpArmor) с поля боя, монстр же может атаковать неограниченно долго и не может подымать аптечки и броню. Интеллект монстра руководствуется неким своим текущим режимом поведения Mode (это может быть, скажем, яростная атака или стрельба в отступлении в игрока), а также запасом своих здоровья и брони (атаковать, когда много, отступать, когда мало). Вот примерный код:
Где тут «неправильный» дизайн? И как его сделать «правильным»? Ваш ход, сэр. Ну-ну, напихать в родителя всё, что только можно... Тогда действительно непонятно, зачем нужно наследование. Не понял. Если твои наследование и полиморфизм здесь ничего не дают (кроме лишнего геморроя с ворохом классов, для которых ещё нужно создавать объекты – по сути вспомогательные), то зачем вообще их тут было использовать? Давай-ка не будем наводить тень на плетень. Если бы всегда от наследования и (или) виртуальных функций можно было б освободиться так же легко, как это сделал я, смысл в их использовании был бы под сомнением. Я всего лишь клоню к тому, что наследование в твоём примере не нужно и только загромождает код, а следовательно, такой пример использования полиморфизма неудачен. Это сообщение отредактировал(а) UnrealMan - 14.7.2006, 09:26 |
|||
|
||||
| Fazil6 |
|
||||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Ладно. Примем твою идею с общностью и необходимостью доступа к этим данным из наследников. Используем защищенный интерфейс. Хорошо. Избранный вариант самый гибкий, самый красивый, самый короткий и самый опасный. Это немногим лучше чем открытые данные. Этот интерфейс будет использоваться именно как доступ к переменным (ты так и пользуешься). Весь код использующий этот интерфейс становится зависимым от его реализации. Опять же, имя метода для установки значения Get - это плохой дизайн. Если уж делать, то
совсем не для того, чтобы размазывать реализацию по нескольким классам.
не думаю, что первоочередная задача программиста неиспользование виртуальных функций. Я не считаю, что твой способ без классов чем-то лучше, и посмотри на название ветки - это был не пример использования полиморфизма, а пример неиспользования доступа к данным. |
||||||||||
|
|||||||||||
| Meeer |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 3.6.2006 Где: Ukraine Репутация: нет Всего: нет |
Вот почитал-почитал всю эту дискуссию.
Нам Rockie дает вырезку из какой-то книги. Как мы видим Fazil6 также читал (или читает) эту самую книгу, и
Fazil6 Я тебя понял. Но это в теории так идеально. А на практике довольно таки неудобно (судя из твоего примера там больше путаницы). Тем более всеравно те же самые значения передаются как параметр "ООП С++", автор Айра Пол, второе издание:
|
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |