| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Зачем людям наследование? |
| Автор: Tobuk 22.12.2009, 16:05 | ||
В чем преимущество данного подхода? (с наследованием) Почему бы просто не объявить point1d и point2d ??? Ни как не пойму. |
| Автор: bsa 22.12.2009, 17:00 |
| Tobuk, наиболее красивые примеры наследования получаются из оконных компонентов. Например, компонент Widget никак не отображается, но при этом у него есть свойства, задающие его размеры и положение. Его наследует компонент Button, который уже имеет собственное изображение и реакцию на клики и пр... Так же его наследует компонент TextEdit, который умеет отображать текст... и так далее |
| Автор: Tobuk 22.12.2009, 17:31 | ||||
Меня интересует зачем пишут ТАК:
далее
Кроме этих двух классов ничего больше нет. Вот вопрос. Зачем нужен класс A? Это реальный пример из HGE |
| Автор: Lazin 22.12.2009, 17:36 |
это интерфейс |
| Автор: Alca 22.12.2009, 17:44 | ||||
Чтобы в каждом производном класса могла быть своя реализация ATAATTAA(). |
| Автор: Tobuk 22.12.2009, 17:48 | ||
спс, но книги по С++ я читал. я говорю про реальный проект. HGE Там есть только 1 класс и 1 "интерфейс". Так какие другие? Чем удобен интерфейс? Не пойму. |
| Автор: Alca 22.12.2009, 17:55 | ||
| http://ru.wikipedia.org/wiki/Интерфейс_(объектно-ориентированное_программирование) Добавлено @ 18:01
Возможно, на будущее |
| Автор: baldina 22.12.2009, 18:02 | ||||||||||||
| Есть несколько аспектов, связанных с наследованием. 1. Скорость и качество разработки. Использование наследования уменьшает необходимость повторного кодирования и, вследствие, число возможных ошибок.
В этом классе мы добавляем функционал для работы с цветом. Прочий функционал, общий для всех точек - создание точки, рисование, математика, трансформация и т.д., просто используем. 2. Полиморфизм (в С++ это использование виртуальных функций; неотделимо от наследования) позволяет строить изящные и эффективные архитектурные решения, использующие динамическое определение типа во время исполнения для вызова соответствующего метода (функции). Типичный пример - отображение элементов управления (виджетов):
Этот простой код будет рисовать кнопки, окна, поля ввода и проч., в зависимости от того на какие конкретные объекты указывают указатели в widgets. Для этого метод paint() должен быть объявлен виртуальным в базовом классе. 3. Объектный подход, использующий декомпозицию типов и объектов. Механизм наследования помогает выражать этот подход естественным образом, т.е. встроенными средствами языка. Декомпозиция - важнейший метод инженерии, в т.ч. программной, упрощающий анализ и проектирование и улучшающий качество решения за счет уменьшения связей между компонентами.
Мы раздельно разрабатываем виджет и таймер. таймер ничего не знает про виджет и наоборот. Про интерфейс, абстрактные классы и чистые виртуальные функции. класс, имеющий чистую виртуальную функцию (=0)
называется абстрактным. Например, в примерах выше абстрактным может быть класс Widget:
мы знаем, что все виджеты можно отобразить. но Widget - это общее понятие, нельзя отобразить просто виджет. Можно конкретный - кнопку, окно, поле ввода, картинку... Базовый абстрактный класс говорит, какой интерфейс должны иметь наследники, но не говорит о реализации. Наследники реализуют, каждый по своему. Нельзя создать объект абстрактного класса ("просто Widget"), но можно указатель на абстрактный класс. Тогда будет возможен код из п.2, указатели указывают на конкретные объекты. Добавлено через 7 минут и 26 секунд
Разработчики старались создать расширяемую архитектуру. Что бы при добавлении функционала не переписывать половину заново, а просто добавить необходимое. Есть код, который использует указатель на объект class A. На самом деле указатель указывает на impl_A. Когда решат сделать impl2_A, то код, использующий указатели на А изменять не придется. Его даже перекомпилировать не нужно |
| Автор: Tobuk 22.12.2009, 18:16 | ||||
| baldina о.О Значит если я определю интерфейсные классы A, B и C. Отнаследую от них несколько нормальных классов с реализацией. Потом создам класс G
То я смогу использовать все красиво так:
Это нормальный подход? |
| Автор: GoldFinch 22.12.2009, 19:01 |
| в HGE вообще страшный код, я тоже думаю что динамический полиморфизм там совсем не нужен |
| Автор: baldina 22.12.2009, 19:01 | ||||||
не
а
Конечно! Более чем нормальный Пример:
|
| Автор: Tobuk 22.12.2009, 19:16 |
| baldina Тогда еще вопрос. Если от класса window отнаследовать классы window_windows и window_linux(один будет всегда в ифндефах некомпилирущийся), то это нормально? Я так однажды сделал. Хорошо получилось(код читаемый без всяких ифндефак в каждой строчке), но мне сказали, что так ни кто не делает и нужно написать все в одном файле и нашпиговать все ифндефами. Я послушался, но получилось месиво, а не код. Какой же вариант правильный? |
| Автор: GoldFinch 22.12.2009, 19:23 | ||
| а #ifdef зачем? как максимум
|
| Автор: baldina 22.12.2009, 19:24 | ||
| имхо твой вариант был лучше. гораздее причем еще можно подключать/отключать на уровне сборки проекта (makefile) Добавлено через 58 секунд
помимо typedef видимо желательно вообще исключить из компиляции ненужный код |
| Автор: bsa 22.12.2009, 21:05 |
| Tobuk, того кто это сказал больше не слушай, он в общем не прав. Хотя он прав с точки зрения производительности. Поэтому, в каждом конкретном случае стоит использовать свои методы. Например, можно использовать http://insidecpp.ru/patterns/pimpl_idiom/, можно использовать технологию, про которую написали выше GoldFinch и baldina. А вот кучу #ifdef/#endif лучше не использовать. Как вариант, я для себя возможным представляю только небольшие вставки на пару строчек, если их очень мало. |