0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
||||||
1 | ||||||
виртуальные функции07.04.2011, 18:40. Просмотров 6461. Ответов 14
Метки нет Все метки)
(
Здравствуйте.Перечитал различные статьи,но не могу до конца вникнуть в смысл использования виртуальных функций.Для взаимного понимания привожу свой код:
Вопрос: в чем смысл использования виртуальных функций если я и обычными методами могу переопределить/изменить базовые функции в классе наследнике???
0
|
|
07.04.2011, 18:40 | |
Виртуальные и чисто виртуальные функции
|
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
08.04.2011, 22:25 [ТС] | 2 |
Пожалуйста,помогите кто знает.
0
|
![]() 5041 / 3102 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
|
|
08.04.2011, 22:29 | 3 |
Сейчас покажу наглядно.
0
|
Модератор
![]() 8329 / 6181 / 829
Регистрация: 14.02.2011
Сообщений: 21,478
|
|||||||||||
08.04.2011, 22:38 | 4 | ||||||||||
виртуальные функции это очень интересно
например
и приведешь их к базовому классу A например так
а если объявишь виртуальными то каждый раз своя
2
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
08.04.2011, 22:56 [ТС] | 5 |
Спасибо.По вашему примеру с указателями немного понял,но не могу нарисовать полную картину применения виртуальной функции.В букварях пишут,что это основа для динамического изменнения,в статике используются перегрузки функций....Блин все равно не доходит до конца.
0
|
![]() 5041 / 3102 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
|
||||||
08.04.2011, 23:00 | 6 | |||||
Фух... Код получился больше, чем я предполагал, но он показывает всю мощь динамического связывания и виртуальных функций. Здесь пользователь самостоятельно может задавать последовательность и количество задаваемых фигур, на этапе компиляции неизвестно, в какой ячейке массива shapes какая фигура лежит. Обратите внимание на строку std::cout << shapes[i]->area() << std::endl;. Весь остальной код, по сути, только для красоты, и вся суть в этой строке. Она означает, что, даже не зная на этапе компиляции, какая фигура где находится, мы можем для любой фигуры использовать просто вызов функции area, и автоматически будет вызвана своя функция для каждой фигуры. Полагаю, возникнут вопросы, если так, обращайтесь - растолкую, что не понятно.
3
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
08.04.2011, 23:18 [ТС] | 7 |
Спасибо большое,но код слишком объемный.Можно пояснить "даже не зная на этапе компиляции, какая фигура где находится, мы можем для любой фигуры использовать просто вызов функции area, и автоматически будет вызвана своя функция для каждой фигуры" ? Или еще лучше показать пример на моем коде,что нельзя сделать без использования виртуальных функций.
0
|
![]() 5041 / 3102 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
|
|
08.04.2011, 23:26 | 8 |
![]() Решение
Опишу суть своего кода:
У нас есть абстрактный родительский класс Shape - фигура. В нём объявлена чисто виртуальная функция area - площадь. От этого класса наследуют три дочерних класса - Square, Triangle, Circle - квадрат, треугольник, круг. В каждом из них функция вычисления площади конкретизируется (т.е. пишется реализация, для каждого класса, естественно, своя). Затем, в основной функции, создаётся вектор указателей на Shape - на абстрактный родительский класс. В цикле мы предлагаем пользователю варианты фигур, которые он может создать. Пользователь может создать одну фигуру, может 3, а может 10. Они могут идти в любой последовательности (при каждом запуске разной). Т.е. на этапе компиляции мы ничего не знаем о будущей структуре вектора shapes (какие фигуры, сколько их и в какой они созданы последовательности). В итоге, скажем, пользователь насоздавал 1000 разных фигур. И тут в игру вступает позднее связывание. Поскольку как в родительском классе (без реализации), так и в дочерних (с реализацией) есть функции area, то нам не обязательно каждый раз знать, какая фигура в какой ячейке находится. Нам достаточно в цикле вызывать функцию area для каждой ячейки массива shapes, а уж какая конкретно будет вызвана функция (ведь площадь каждой из трёх фигур вычисляется по-разному) - это будет определено автоматически и нам об этом думать не надо. Вообще, код не такой уж и большой, основную часть занимают красивости, вывод и т.д. Содержательная часть - три класса и не больше 10 строчек в main.
3
|
1483 / 631 / 62
Регистрация: 31.03.2009
Сообщений: 2,035
|
|
08.04.2011, 23:29 | 9 |
![]() Решение
Твой код похож на безумие. Он заставляет меня плакать.
Динамический полиморфизм, реализуемый при помощи наследования и виртуальных функций, позволяет вызывать функции, реализованные в наследниках через указатель или ссылку на базовый класс. Есть, допустим, у тебя класс Фигура. В нём есть абстрактная функция Отрисовать. Фигура не умеет себя рисовать, потому что понятия не имеет, что она за фигура такая. Ты наследуешь от Фигуры конкретные классы Квадрат, Круг, Треугольник. В каждом из этих классов реализуешь функцию Отрисовать. Теперь Круг умеет себя рисовать, Квадрат умеет себя рисовать и Треугольник умеет себя рисовать. Теперь у тебя есть задача: создать кучу объектов этих классов и рисовать их. Как это сделать? Создаёшь массив указателей на объекты базового класса, т.е. класса Фигура. Любой указатель на объект класса-наследника ты можешь привести к указателю на объект базового класса, а потому можешь с помощью new создавать объекты классов Квадрат, Круг, Треугольник и помещать их в этот массив. Если теперь пройтись по всем элементам массива, то вызывая функцию базового класса Отрисовать, реально будет вызываться функция наследника. То есть в этом массиве ты хранишь много-много разных фигур, говоришь им Отрисовать, а каждая из них сама рисует себя как нужно.
4
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
09.04.2011, 00:08 [ТС] | 10 |
Спасибо огромное silent_1991 и NightmareZ за столь детальное разъяснение.Хочу задать пару вопросов по коду:
0
|
бжни
2470 / 1680 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
09.04.2011, 00:13 | 11 |
Babulesnik, http://ru.wikipedia.org/wiki/Т... ых_методов
1
|
![]() 5041 / 3102 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
|
|
09.04.2011, 00:25 | 12 |
![]() Решение
Babulesnik, так ведь в том и суть виртуальных функций! Что мы не обязаны знать, к какой фигуре какая функция относится, главное, что программа может это узнать.
На самом деле реализация виртуальных функций не регламентирована стандартом, регламентировано только поведение, но обычно виртуальные функции реализуются через указатели на функции. В каждом экземпляре класса расположен указатель на таблицу указателей на функции (так называемая vtable) класса, и при вызове виртуального метода через указатель на базовый класс, на самом деле мы ведь попадаем в экземпляр того класса, на который фактически указывает этот указатель (т.е. на экземпляр некоторого дочернего класса), и здесь натыкаемся на vtable, в которой расположены указатели уже на конкретные функции соответствующих классов.
3
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
09.04.2011, 00:42 [ТС] | 13 |
Всем большое спасибо,вроде дошло )))
0
|
Модератор
![]() 8329 / 6181 / 829
Регистрация: 14.02.2011
Сообщений: 21,478
|
|
09.04.2011, 07:02 | 14 |
"еще одно последнее сказанье"
объект абстрактного класса создать нельзя попробуй создай простейшую программу с отладочным кодом(Dedug) и дизасемблируй ее(лучше IDA) и увидишь как реализуется наследование, виртуальные функции....... большинство вопросов отпадет
1
|
0 / 0 / 0
Регистрация: 06.01.2011
Сообщений: 21
|
|
09.04.2011, 16:01 [ТС] | 15 |
0
|
09.04.2011, 16:01 | |
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь. Виртуальные функции виртуальные функции виртуальные функции Виртуальные функции Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |