Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
ramarren14
2 / 2 / 0
Регистрация: 14.07.2011
Сообщений: 49
1

Вопрос по наследованию

09.11.2011, 17:48. Просмотров 2311. Ответов 52
Метки нет (Все метки)

Уже неоднократно перечитывал главы про наследования и все равно до конца не разобрался.
Вот например у нас есть класс Четырехугольник, и мы создаем класс Прямоугольник.
И в том и в другом классе есть функции Площадь и если у них будет одинаковая сигнатура, то вызовется функция того класса, объект которого мы создали. Если же сигнатуры совпадать не будут, то нужно явно указать с помощью оператора ::.
Если мы сделаем функцию площади виртуальной, то при одинаковых сигнатурах вызовется функция своего класса. То же в случае разных сигнатур. То есть единственный плюс объявления функций виртуальными, это то что если мы создадим указатель на объект базового класса, он сможет указывать и на объект производного класса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2011, 17:48
Ответы с готовыми решениями:

Вопрос по наследованию
Вопрос насчёт передачи аргументов в конструктор базового класса(создания...

Вопросы по наследованию
Вопрос ещё по конструкторам Допустим есть система классов class A { ...

Задание по наследованию классов
Создать иерархию классов : линия - прямоугольник - пирамида. Все классы должны...

Задача по наследованию в C++, нужно реализовать некоторые моменты
Написать программу с объектами и реализовать наследование. Ситуация: Klimat...

Задача по наследованию. Не понимаю некоторые моменты в формулировке задания
Здравствуйте! Вот есть задание: Описать базовый класс СТРОКА Обязательные...

52
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
10.11.2011, 20:30 41
Цитата Сообщение от LosAngeles Посмотреть сообщение
Переключаем версию на релиз и нет никаких ассертов, что мы получаем?
Как бы игнорирование ошибки не есть её исправление...
Отключать ассерты в релизе не есть хорошо. Стандартный ассерт УГ, сакс и фтопку.
0
Bers
Заблокирован
10.11.2011, 20:35 42
Цитата Сообщение от Deviaphan Посмотреть сообщение
Ведь согласись, что следующая реализация метода не может быть у квадрата
Да, не может. Поэтому, квадрат можно отнаследовать от прямоугольника, но нельзя отнаследовать от кирпича.

Если ваш манипулятор ожидает на входе кирпич, то он и должен принимать только кирпичи, а не все мыслимые и не мыслимые прямоугольники.

Если манипулятор ожидает на входе все мыслимые и не мыслимые прямоугольники, то он должен быть готов к тому, что придти может и кирпич, и квадрат.

Если манипулятор не делает различий между кирпичом и квадратом, но в рантайме ломает все квадраты - это архитектурный фейл.

Проектирование по принципу: "Я не запрещаю тебе быть квадратом, но если ты реально окажется квадратом, то я заломаю нафег всю программу"

Это проектирование по принципу: "Здесь, здесь и здесь я закопаю мину. Специально, что бы взрывать полностью работоспособный процесс".

Добавлено через 2 минуты
Цитата Сообщение от LosAngeles Посмотреть сообщение
Переключаем версию на релиз и нет никаких ассертов, что мы получаем?
Кашу в голове, и мину замедленного действия в коде мы получаем. И программиста, который не вполне себе осознает, для чего вообще существуют ассерты
1
Le Thaw
10.11.2011, 20:37
  #43

Не по теме:

Bers, зачетные цитаты.

0
LosAngeles
Заблокирован
10.11.2011, 20:39 44
Цитата Сообщение от Deviaphan Посмотреть сообщение
Совершенно верно! Метод должен называться MakeWidthBigger и тогда он становится правильным. С данным названием он недоопределён и его поведение зависит от фактического типа объекта, что не есть хорошо.
нет, от изменения названия он правильнее не станет ни на йоту. Я вправе ожидать от квадрата, что его стороны будут равны друг другу в любой момент времени, а не подбирать функцию исходя из её названия(что за лол?) и гадать, а не приведёт ли она квадрат в противоречивое состояние, что в случае наследования от прямоугольника сделать легко. Так что если найдётся хоть один способ привести квадрат в противоречивое состояние через его же интерфейс, значит вся иерархия тухлая.
0
Bers
Заблокирован
10.11.2011, 20:41 45
Цитата Сообщение от Deviaphan Посмотреть сообщение
но реализация полиморфизма никак не регламентирована и разработчики компиляторов вольны реализовывать его как им вздумается. Поэтому о "низкоуровневой" реализации лучше даже и не задумываться. Только если с привязкой к компилятору.
Ну как бы, на самом деле и не нужно об этом задумываться. Нужно просто понимать, как он должен работать.

Главный принцип: указатель базового типа запустит метод потомка, если сам указатель будит указывать на этого потомка, а сам метод будит виртуальным.

Если метод будит не виртуальным, запустится базовый метод.

По моему, вполне достаточно для понимания)
0
LosAngeles
Заблокирован
10.11.2011, 20:41 46
Цитата Сообщение от Bers Посмотреть сообщение
Кашу в голове, и мину замедленного действия в коде мы получаем. И программиста, который не вполне себе осознает, для чего вообще существуют ассерты
всё это на мыло мейерсу скинить и его боссу, давно пора уволить этого идиота, а книжки сжечь!
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
10.11.2011, 20:43 47
Цитата Сообщение от Bers Посмотреть сообщение
Поэтому, квадрат можно отнаследовать от прямоугольника
Ну как может-то?
Есть метод изменения ширины, который должен изменять ширину. В квадрате же он должен синхронно изменять и высоту. Метод "ИзменитьШирину", который изменяет высоту это ведь не правильно. С этим ты готов согласиться? Это нарушение логики. Т.е. для квадрата методы ЗадатьШирину и ЗадатьВысоту должны быть закрыты и вместо них должен быть добавлен метод ЗадатьРазмер. Т.е. квадрат не является прямоугольником с точки зрения интерфейса (с точки зрения геометрии, разумеется, он является прямоугольником и четырёхугольником), и если и можно его наследовать, то только закрытым наследованием от rectangle.
0
Сыроежка
Заблокирован
10.11.2011, 20:43 48
Цитата Сообщение от LosAngeles Посмотреть сообщение
всё это на мыло мейерсу скинить и его боссу, давно пора уволить этого идиота, а книжки сжечь!
Вы путаете себя с Майерсом! Не надо себя отождествлять с Майерсом. Старайтесь говорить от себя лично и приводить конкретные примеры, которые убеждают в вашей правоте.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
10.11.2011, 20:46 49
Цитата Сообщение от LosAngeles Посмотреть сообщение
он правильнее не станет ни на йоту
Станет. В нём будет разрешено изменение ширины и запрещено изменение высоты. Что будет соответствовать названию. Слово СделатьБольше не уточняет, каким именно образом он будет становиться больше, поэтому запрет изменения высоты не корректен.

Добавлено через 1 минуту
Цитата Сообщение от Bers Посмотреть сообщение
о моему, вполне достаточно для понимания
Абсолютно да.) Просто слово "низкоуровневое" наводит на более глубокие изыскания.)
0
Bers
Заблокирован
10.11.2011, 21:02 50
Цитата Сообщение от Deviaphan Посмотреть сообщение
Есть метод изменения ширины, который должен изменять ширину. В квадрате же он должен синхронно изменять и высоту. Метод "ИзменитьШирину", который изменяет высоту это ведь не правильно. С этим ты готов согласиться? Это нарушение логики. Т.е. для квадрата методы ЗадатьШирину и ЗадатьВысоту должны быть закрыты и вместо них должен быть добавлен метод ЗадатьРазмер. Т.е. квадрат не является прямоугольником с точки зрения интерфейса
Я не согласен.
Для прямоугольника: Изменяем высоту - изменится высота.
Изменяем ширину - изменится ширина.

Для квадрата - изменяем хоть ширину, хоть высоту. Все равно запускается родной для квадрата метод "изменить размер"

То есть метод "изменить ширину" для квадрата такой же правомерный, как и для любого другого прямоугольника. Но реализация метода отличается тем, что для квадрата изменится не только ширина, но и высота.

Я имею полное право изменить ширину квадрата. Что мне мешает это сделать?
Я не имею права для квадрата изменить ширину, а высоту оставить прежней. Но об этом контракте позаботится сам квадрат. Его реализации методов "изменить ширину/высоту".

Для прямоугольника метод "изменить ширину" - изменит ширину фигуры.
При этом, может изменится и высота, если фигура - квадрат. Что здесь нелогичного?

Я хочу сказать, что у прямоугольника при изменении ширины, высота не обязана сохранять прежнее значение.

Вы можете сказать: но это тупо! Зачем квадрату вообще иметь методы "изменить ширину/высоту", если идеологически ему нужен только один метод "ИзменитьРазмер" ?

Тут я с вами соглашусь полностью. Для квадрата первые два интерфейса кажутся излишними.
Но это - зависит от архитектурного решения. Такое решение может быть не самое красивое, с точки зрения минимализма, но вполне приемлимое.

Об этом и пишет Маерс (я по крайней мере так его понял) - о том, что оо-программирование, это в первую очередь программирование в терминах интерфейсов.

И при установлении различных отношений между классами, в первую очередь нужно согласовывать интерфейсы предков и потомков, что бы не получилось "аляписто".

Что бы не пришлось на некоторые методы вообще ставить заглушки (метод как бы есть, а использовать его нельзя).

Что бы не получилось что методов больше, чем требуется объекту по смыслу.

Хотя пример для иллюстрации он привел фейловый

Добавлено через 1 минуту

Не по теме:

Цитата Сообщение от Deviaphan Посмотреть сообщение
Абсолютно да.) Просто слово "низкоуровневое" наводит на более глубокие изыскания.)
ну это я так, понтануццо просто хотел))
Заодно интересную ссылку народу предоставил)

0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
10.11.2011, 21:31 51
Цитата Сообщение от Chelioss Посмотреть сообщение
С указателями понятно. Без виртуальности будет вызываться метод класса Base, потому что тип указателя - Base.
Но не понятно, почему A.call() вызывает метод f() класса Base, если объект A имеет тип Derived, в котором метод f() переопределен.
Вот пример, где вызывается именно метод класса Derived.
В моем примере написано: A.Call(); Который НАСЛЕДУЕТСЯ и НЕ ПЕРЕОПРЕДЕЛЯЕТСЯ.
Этот A.Call() и вызывает внутри себя базовый метод f(), который не виртуальный.
А если сделать f() виртуальным, то A.Call() будет вызывать f() по типу объекта А.
0
Chelioss
181 / 181 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
10.11.2011, 22:35 52
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
В моем примере написано: A.Call(); Который НАСЛЕДУЕТСЯ и НЕ ПЕРЕОПРЕДЕЛЯЕТСЯ.
Call() нет, а f() переопределяется. Не совсем очевидно, почему вызывается f класса Base, если f переопределена.
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
11.11.2011, 08:44 53
Цитата Сообщение от Chelioss Посмотреть сообщение
Call() нет, а f() переопределяется. Не совсем очевидно, почему вызывается f класса Base, если f переопределена.
Вот это и есть самое важное в понимании виртуальных функций...
Потому как при трансляции базового класса компилятор НИФИГА не знает о наследниках. Поэтому НАМЕРТВО связывает CALL со своей f() ПРИ КОМПИЛЯЦИИ.

Если же мы пишем virtual, то это мы подсказываем компилятору: погоди намертво связывать, наследники будут. И компилятор формирует код, который связывает вызов ПРИ ВЫПОЛНЕНИИ программы...
1
11.11.2011, 08:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2011, 08:44

"Предпочитайте композицию наследованию"
Привет. В книге "Стандарты программирования на С++" есть совет 34: ...

Написать простейшую программу по "перегрузке" и "наследованию"
написать простейшую программу на СИ++ по "перегрузке" и "наследованию". заранее...

Вопрос по массивав, "институтский" вопрос.
Готовлюсь к летней сессии по программированию. С++ Есть такая вот задачка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
53
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru