4 / 4 / 3
Регистрация: 13.07.2014
Сообщений: 129
|
|
1 | |
В чем смысл полиморфизма19.07.2015, 22:57. Показов 2070. Ответов 17
Метки нет Все метки)
(
Объясните, пожалуйста, смысл полиморфизма. Не могу никак вникнуть. Где и как он используется? И примерчик, пожалуйста
0
|
|
19.07.2015, 22:57 | |
Ответы с готовыми решениями:
17
В чем смысл указателей? В чем смысл виртуальных функций?
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
19.07.2015, 23:56 | 2 |
прочитайте книги, статьи.
0
|
4 / 4 / 3
Регистрация: 13.07.2014
Сообщений: 129
|
|
20.07.2015, 00:00 [ТС] | 3 |
rikimaru2013, читал. Вроде как понял, но вот примера нормального не нашел. По этому так и не понял, зачем полиморфизм нужен
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||
20.07.2015, 00:19 | 4 | |||||
В более крутых проектах: есть понятие в игре юнит - у него виртуальный метод moveTo(); Кто-то идёт пешком, какая-то гарпия летает, кто-то телепортируется по местности, но у всех есть метод moveTo(), который они переопределили для себя. И если появится еще 1 вид передвижения, это не беда, унаследуем, переопределим и будет он ... к примеру, нырять под землю и в нужной точке выныривать.
0
|
![]() 8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
|
||||||
20.07.2015, 09:53 | 5 | |||||
есть собака, и кошка.
и то, и другое - животные. собака лает. кошка мяукает.
такие классы любят называть "интерфейсы". он задает методы управления всеми возможными животными. в данном случае он сообщает: каким бы ни было животное, но у него обязательно будет метод sound, который заставит животное издавать звуки. и есть кучка наследников: кошки, собаки. это - разные классы. у них разное поведение. в данном случае они по разному звучат. однако несмотря на их различия, что бы они начали звучать в обоих случаях используется один и тот же метод. поэтому, даже не зная точно, кто это: кошка, или собака, мы можем заставить их звучать. то есть мы можем выполнять действия над объектами не зная точно, что именно это за объекты. главное что бы у них у всех был одинаковый интерфейс. зачем это нужно? вот другой пример: допустим, мы решили создать игрушку. в игрушке будут бегать разные юниты, и стрелять друг в друга из разных видов вооружения. поскольку над проектом будет работать несколько программистов, то нужно так распределить наши роли, что бы мы друг другу не мешались. допустим, вы будете писать код юнитов. а я - код вооружения. но как вы сможете писать код юнита, если вооружения ещё никакого нет? как вы научите своих солдатиков стрелять из оружения, если код оружия ещё не написан? и вот, мы с вами договариваемя: у любого вида оружия есть интерфейс IWeapon, у которого есть метод Fire. что бы юнит сделал выстрел, он должен вызвать этот метод для объект "оружия". и уже не важно что это за оружие, но если у него есть такой метод, ваш юнит сможет сделать выстрел. таким образом, благодаря полиморфизму, становится возможным солдатикам стрелять из любого вида оружия (в том числе из такого, чей код ещё даже не написан). и становится возможным налету (в момент выполнения программы) заменить одно оружие на другое. солдатик достает пистолет и делает: "пиф-паф!" а потом достает базуку и делает: "бууумс!" при этом солдатик не знает как на самом деле устроен объект, из которого он стреляет. ему просто пофигу, он сможет стрелять из любого оружия, лишь бы у него был спуской крючок: IWeapon::Fire это делает возможным: 1. командную разработку программного обеспечения, так, что бы никто никому не мешался. и никого не ждал. 2. гибкость (можно налету подменять поведение, за счет подмены объектов) 3. расширяемость (что бы добавить ещё одну пушку - достаточно просто унаследоваться от интерфейса, и реализовать определенные методы, и все солдатики априори уже смогут пользоваться новым оружием без изменений в своем коде.).
0
|
4 / 4 / 3
Регистрация: 13.07.2014
Сообщений: 129
|
||||||||||||||||
20.07.2015, 10:13 [ТС] | 6 | |||||||||||||||
Спасибо большое!
Но вот я так и не понял этого:
0
|
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
|
|
20.07.2015, 10:20 | 7 |
Смысл полиморфизма в том, что вы вместо базового класса можете использовать наследника. Например (тут рядом моя тема есть) мне нужно выводить информацию из объекта. я передаю ему ссылку (или указатель) на ostream. если пользователь выбирает пункт меню "вывод в файл" для вывода передаётся объект ofstream, если же пользователь выбрал "вывод в консоль", то передаётся cout.
0
|
Модератор
![]() 13410 / 10520 / 6285
Регистрация: 18.12.2011
Сообщений: 28,091
|
||||||
20.07.2015, 10:23 | 8 | |||||
Обратите внимание на то, что в первом случае указателю на БАЗОВЫЙ класс присваивается адрес ПРОИЗВОДНОГО класса.
В этом случае obj_1->AnyFunc(); вызывает виртуальный метод ПРОИЗВОДНОГО класса, т.е. того класса, адрес которого был присвоен. Соответственно, если присвоен адрес базового класса, то obj_2->AnyFunc(); вызывается метод базового класса. Second *obj_1 = new Second;obj_1->AnyFunc(); - естественно, вызовется метод производного класса. А для вызова метода базового класса придется написать
0
|
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
|
||||||
20.07.2015, 10:28 | 9 | |||||
вот код для моего примера:
0
|
![]() 8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
|
|
20.07.2015, 10:29 | 10 |
объясняю на примере:
напишите пожалуйста функцию, которая сможет принимать любые объекты : First/Second , может быть в будущем ещё наследника добавим. то есть функция обязана априори принять любого члена иерархии классов. и дернуть ему функцию AnyFunc. как вы это сделаете? ----------------------------------------------------------------------------------- вот у вас есть кошка и собака, а может быть ещё и волк, или лиса. не важно. у них у всех есть метод "звучать". напишите функцию, которая умеет принимать объекты любого типа животного, и заставлять его звучать. что бы вам не пришлось писать по функции на каждый конкретный тип животного. я хочу, что бы вы написали только одну. но эта одна сможет заставить звучать любого животного, которого её пришлют.
1
|
Модератор
![]() 13410 / 10520 / 6285
Регистрация: 18.12.2011
Сообщений: 28,091
|
|
20.07.2015, 10:51 | 11 |
VVildVVolf, разъясните подробно, какое отношение имеет Ваш код к теме "Полиморфизм".
0
|
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
|
|
20.07.2015, 10:59 | 12 |
функция print принимает указатель на ostream, при этом в функции main эта функция вызывается с передачей аргументов разных типов.
п.с. честно признаюсь, в нюансы именно стримов не вникал досконально, что откуда наследуется и к чему приводится, но использование полиморфизма ВЫГЛЯДИТ примерно так.
0
|
Модератор
![]() 13410 / 10520 / 6285
Регистрация: 18.12.2011
Сообщений: 28,091
|
|
20.07.2015, 11:56 | 13 |
Оператор << не является методом класса ostream.
это глобальный перегруженный оператор. Поэтому в никакого полиморфизма нет. Кроме того, даже если бы и был, то операция разыменования *os приводит к тому, что этот метод вызывался бы как обычный, а не как виртуальный.
0
|
82 / 1 / 0
Регистрация: 08.10.2012
Сообщений: 54
|
|
20.07.2015, 12:01 | 14 |
даже если бы и был - это к полиморфизму или к
?
суть здесь не в перегрузке оператора <<, а в том, что передаются экземпляры разных классов, что влияет на итоговое поведение соответственно. или же в обоих случаях передаются экземпляры одного и того же класса?Оо
0
|
Модератор
![]() 13410 / 10520 / 6285
Регистрация: 18.12.2011
Сообщений: 28,091
|
|
20.07.2015, 12:11 | 15 |
VVildVVolf, Вы продемонстрировали не полиморфизм, а родственность производных классов.
Т.е. то, что указателю на базовый класс можно присваивать адрес производного класса без каких-либо преобразований.
0
|
236 / 196 / 21
Регистрация: 04.06.2014
Сообщений: 1,309
|
|
20.07.2015, 12:13 | 16 |
Ну, на бытовом уровне, смысл полморфизма, когда друзья Вам дают кличку. Вы, уже называетесь в их среде по-другому, но Ваша суть от этого не изменилась-ведь? Вот, в принципе, и всё
![]()
0
|
![]() 8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,762
|
||||||
20.07.2015, 12:18 | 17 | |||||
есть. статический.
обычно он реализуется посредством перегрузки, либо посредством шаблонов. но в данном случае он был реализован за счет приведения по иерархии наследования. это работает, потому что сам по себе std::ostream не более, чем обертка, которая делегирует задачу своему очень даже полиморфному внутреннему механизму буфера вывода. http://www.cplusplus.com/reference/ios/ios/rdbuf/ ничего подобного.
он продемонстрировал два принципиально разных поведения (вывод в консоль, или вывод в файл), осуществляемых через единый интерфейс для объектов разных типов. это и есть красноречивый пример полиморфизма. "родственность производных классов" - это конечно круто звучит. учитывая, что так можно обозвать любое проявление динамического полиморфизма, осуществляемого посредством виртуальных функций-членов.
3
|
4 / 4 / 3
Регистрация: 13.07.2014
Сообщений: 129
|
|
23.07.2015, 17:31 [ТС] | 18 |
Большое всем спасибо!
0
|
23.07.2015, 17:31 | |
Помогаю со студенческими работами здесь
18
Dynamic_cast и static_cast: в чём смысл?
В чём смысл return в main()? class classname; В чем смысл? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |