В чем смысл virtual?

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
v1nt
Сообщения: 6
Зарегистрирован: 07 июл 2004, 16:26
Откуда: СПб

15 июл 2004, 17:13

Объясните плз.
Зачем метод делается виртуальным?
Только для того что бы методы родителей обращались к нужным методам потомков? Или суть намного глубже.
to be continue...
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

15 июл 2004, 17:32

Именно для этого, если ты правильно понимаешь то, о чём говоришь. А это не так и мало потому, что несчесть количества мест, где виртуальные методы могут применяться... :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
v1nt
Сообщения: 6
Зарегистрирован: 07 июл 2004, 16:26
Откуда: СПб

15 июл 2004, 18:40

Да не... мне казалось я все же понимаю о чем говорю ))
Но это уже оффтоп.
to be continue...
Аватара пользователя
Naeel Maqsudov
Сообщения: 2551
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

16 июл 2004, 01:37

Только для того что бы методы родителей обращались к нужным методам потомков?
Какая-то некорректная формулировка...

(Первое)
Динамические и виртуальные методы нужны для того, чтобы их можно было override (to override - вторгаться, вторгнуться). Т.е. при наследовании их можно не просто перекрыть, а вторгнуться в их работу и дополнить ее чем-то еще. При переопределении виртуального метода в новой его реализации можно вызвать старую (родительскую), используя inherited.

(Второе) .... О! То, что Вы как раз имели в виду под тем, что я процитировал выше!
Если переменная Obj1 типа TParent сылается на экземпляр объекта созданого как TChild.Create, то Obj1.VirtualMethod1 будет вызывать метод переопределенны в классе TChild, а не определенный в TParent. Это называется ПОЛИМОРФИЗМ. Т.е., обобщая, это нужно для реализации Object Pascal-ем принципа полиморфизма в объектно-ориентированном программировании.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 июл 2004, 11:47

Naeel Maqsudov, относительно второго пункта всё правильно, именно о полиморфизме и шла решь с амого начала, только всё было сказано более просыми словами. А вот относительно первого - можно поспорить. Если метод базового класса невиртуальный - его всё равно можно вызвать :) Пример не показателен :)

В качестве ещё одного плюса идеологии виртуальных методов, вместо пункта 1 из "лекции" глубокоуважаемого Naeel Maqsudova, я бы отметил возможность создания т.н. чисто виртуальных методов, которые своим присутствие добавляют в vtable лишнюю ячейку, но забивают её нулями. Таким образом в иных своих методах базовый класс сможет вызывать этот виртуальный метод, который будет определен позже, в потомке (а это даёт огромное количество плюсов). Такая технология называется поздним связыванием, класс, который имеет хотя бы один чистовиртуальный метод называется абстрактным, класс же, все методы которого являются публичными и чистовиртуальными (при этом поля отсутствуют) называется интерфейсом (он как бы задаёт поведение своих потомков, но при этом ничего конкретного о нюансах этого поведения не говорит). Последняя конструкция широко используется в COM технологии.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Naeel Maqsudov
Сообщения: 2551
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

20 июл 2004, 02:38

А вот относительно первого - можно поспорить.
Спорить бессмысленно - RTFM по слову virtual. Там ясно прописано назначение virtual. (раздел справки "Virtual and dynamic methods")
Если метод базового класса невиртуальный - его всё равно можно вызвать
Да, но это не пример мастерства и хорошего стиля, а вынужденная мера, на которую идут из-за ошибок, допущенных на стадии проектирования объектных сущностей.


Термин "Позднее связывание" к данной области вообще никакого отношения не имеет! Не путайте начинающих!

За дополнение по поводу абстрактных методов спасибо. Абстрактные методы применяются в рамках объектно-оринтированного проектирования для создания АБСТРАКТНЫХ КЛАССОВ. (Абстрактные классы и интерфейсы это совершенно разные вещи!) Абстрактный класс - это наиболее общая реализация объектной сущности. Она описывает общие принципы функционирования классов, порождаемых от данного. Экземплярами (инстансами) абстрактных классов никогда не пользуются (за очень редким исключением, но это примеры плохого стиля). Так например, если в программе присутствует вызов конструктора абстрактного класса, то компилятор обязательно выдает об этом предупреждение.
Пример абстрактного класса является TStrings - методы Clear, Delete, и т.п. в нем абстрактные.

Поэтому при
Var S:TStrings;

Создание экземпляра S:=TStrings.Create - это ошибка,
а S:=TStringList.Create - нет.

Вывод - использование абстрактных классов - это расширенная возможность полиморфизма. То что Вы назвали поздним связыванием - это ПОЛИМОРФИЗМ.

Конечно, из абстрактных классов в последствии (когда на почве ООП выросло дерево под названием COM) выросли ИНТЕРФЕЙСЫ, которые ВООБЩЕ ИЗОЛИРОВАНЫ И ОТ КОНКРЕТНЫХ, И ОТ АБСТРАКТНЫХ РЕАЛИЗАЦИЙ МЕТОДОВ И СВОЙСТВ.

К иходному вопросу все это имеет отношение лишь в том смысле, что все абстрактные методы должны быть переопределены в классах-потомках с помошью virtual, а пользоваться абстрактными классами нужно для того, чтобы иметь возможность, используя полиморфизм, программировать действия определяемые над всеми экземплярами потомков данного класса по наиболее общим правилам. Т.е. иметь возможность применить некую процедуру не к экземплярам данного абстрактного класса (этих экземпляров попросту НЕ БЫВАЕТ), а экземплярам его потомков.
Ответить