![]() |
|
Модераторы: bsa |
![]()
|
|
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Здравствуйте, форумчане. Не затруднитесь ли вы мне объяснить, для чего нужны?
|
|||
|
||||
| bsa |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Они нужны для унификации интерфейса доступа к разным объектам.
Например, разные программы управляются мышкой и клавиатурой. Но выполняют они совершенно разные вещи. Так вот, мышка и клавиатура - это интерфейс. Он одинаков для всех, но разные программы реагируют на действия по разному. Так же и виртуальные функции. У тебя есть класс:
Это сообщение отредактировал(а) bsa - 17.7.2011, 16:01 |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
в книжках найдешь объяснение. что за вопросы... это форум а не бесплатные курсы по изучению ЯП. Это сообщение отредактировал(а) boostcoder - 17.7.2011, 16:04 |
|||
|
||||
| Сыроежка |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 127 Регистрация: 24.6.2011 Репутация: 1 Всего: 1 |
Сначала хотел бы вам посоветовать, не обращать внимание на грубость некоторых здесь присутствующих. Ьерегите нервы. Что касается вашего исходного вопроса, то виртуальные функции нужны для обеспечения полиморфизма. В данном случае это когда через один интефейс вы можете работать с несколькими реализациями. Полиморфизм обеспечивают помимо виртуальных функций, например, перегрузка функций, когда используется одно имя функции, но на самом деле обеспечивается вызов различных по реализации функций. Самое лучший способ понять их назначение, это составить классический пример с одним базовым классом с именем Shape, который задает интерфейс, и производными классами типа Circle, Triangle, Rectangle. Затем создать все производные классы и попробовать через указатель на базовый класс, вызвать виртуальную функцию для производных классов. То есть я хотел сказать, что на примере понять это проще. Это сообщение отредактировал(а) Сыроежка - 17.7.2011, 19:16 |
|||
|
||||
| ZVano |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 11.12.2006 Где: Украина, Кривой Р ог Репутация: 1 Всего: 4 |
Совершенно верно, но приведу более понятный (с моей колокольни) пример. Представь, что у тебя есть программа - примитивный графический редактор, котрый умеет только рисовать фигуры (Окружности, треугольники, кватраты и т.д.) Алгоритм работы: 1. Пользователь из палитры выбирает фигуру, кидает на холст и задает параметры: 1.1 Общие для всех фигур: тип фигуры, позиция, цвет линий, цвет заливки; 1.2 Частные для фигуры конкретного типа: Окружность - диаметр окружности; Квадрат - длинна ребра квадрата. 2. Новая фигура добавляется в список фигур. 3. Вызывается процедура, которая перерисовывает холст (т.е. очищает и выводит все фигуры из списка). Как это работает с полиморфизмом? 1. Объявляется базовый класс TShape, который содержит набор общих свойств(1.1) и список деклараций общих методов, которые помечены virtual и будут реализованы в потомках. Например: Draw - нарисовать; Rotate - повернуть; Move - переместить. Эти методы и являются виртуальными. 2. Объявляются классы-потомки от TShape, которые реализуют конкретную фигуру. Например TSquare - квадрат; TCircle - окружность; TTriangle - треугольник. В каждом потомке НЕОБХОДИМО реализовать все виртуальные методы родительского класса TShape (Draw, Rotate, Move, ...). При этом реализация ориентируется на конкретный тип фигуры. Например: TCircle.Draw - нарисовать окружность - окружность сама знает как отрисовываться относительно позиции фигуры (точка позиции совпадает с ценром фигуры.) - огружность сама знает как заливаться цветом - заливка от центра Square.Draw - нарисовать квадрат - квадрат сам знает как отрисовываться относительно позиции фигуры (точка позиции совпадает с левым верхним углом фигуры.) - квадрат сам знает как заливаться цветом - заливка от центра, который вычисляется исходя из позиции фигуры и длинны стороны. 3. Созданые объекты добавляются в список объектов базового класса (TShape). 4. Вызывается процедура перерисовки холста (по таймеру, либо по событию). Процедура перебирает все фигуры из списка и вызывает виртуальную функцию Draw. В реальности будет вызвана последняя переотределенная функция объекта (Например, при наследовании "TShape << TRectangle << TSquare" будет вызвана TSquare.Draw несмотря на то, что в TRectangle тоже есть реализация Draw). PS: Если словесное описание непонятно, могу выразиться в коде. Пиши, если что. Это сообщение отредактировал(а) ZVano - 18.7.2011, 14:57 -------------------- НЕ ФЛУДИМ. Пользуемся кнопками "+" или "-" для выражения своего отношения к теме или сообщению. Гуглим "Как правильно задавать вопросы" |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Всем большое спасибо
Компилятор ворчит "error: `int cShape::b()' is inaccessible", но ведь этот метод public и не виртуальный! Причем ошибка относится к 8-й строчке (где объявляется метод b()), но появляется только при том, что присутствует строка obj.b(). Мистика Это сообщение отредактировал(а) Hagrael - 19.7.2011, 09:03 |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Hagrael, по умолчанию классы наследуются с правом доступа private. Поэтому, если ты явно не укажешь другой, то из-вне методы предка будут недоступны. И вообще, причем тут виртуальные методы? У тебя их нет в примере!
Виртуальные методы говорят, что их реализацию можно заменить другой в наследнике. А вот абстрактные методы (virtual int method() = 0;) необходимо заменить в потомке, экземпляр класса которого планируется уже создавать (создать объект абстрактного класса невозможно). Именно с помощью абстрактных методов делается интерфейс. |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Все ясно! Спасибо, форумчане!
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
|
|||
|
||||
| Сыроежка |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 127 Регистрация: 24.6.2011 Репутация: 1 Всего: 1 |
У вас тут несколько ошибок в коде. Во первых, если вы определяете функцию, как возвращающее значение, отиличное от void, то вы должны на самом деле возвращать значение. То есть у вас функция b() объявлена, как возвращающая значение типа int, а на самом деле вы ничего не возвращаете. Во-вторых, чтобы функция была виртуальной, нужно при ее объявлении в базовом классе использовать ключевое слово virtual. В-третьих, производный класс у вас наследует базовый класс, как закрытый. В этом случае открытые функции базового класса становятся, если память не изменяет, закрытыми в производном классе. Поэтому вы не можете вызвать obj.b(); |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Сыроежка, понятно
|
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |