17 / 14 / 3
Регистрация: 21.03.2017
Сообщений: 155

Про dynamic и virtual

14.01.2020, 22:08. Показов 2162. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, пожалуйста. Никак не могу усвоить механизм работы таблиц виртуальных и динамических методов( Кучу описаний прочитал и все не сходится.
Везде пишут, что для полиморфных методов сначала реализация ищется в классе объекта, потом родителя и так далее, выше и выше. А если метод не полиморфный, то он просто вызывается, исходя из типа указателя. Но вот код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type
c1 = class
  procedure m; virtual;
end;
 
c2 = class(c1)
  procedure m; override;
end;
 
c3 = class(c2)
  procedure m; virtual; 
end;
 
c4 = class(c3)
end;
Почему в случае
Delphi
1
2
3
4
var lc: c1;
begin
lc := c4.create;
lc.m;
вызывается метод класса c2, а не c3? Ведь если заменить в c3 virtual на override, то все в порядке, но создав еще одну таблицу виртуальных методов в c3 я прервал цепочку наследования и начал заново.
Получается поиск реализации начался с c2 в данном случае?
Также непонятно, откуда преимущество в скорости VMT перед DMT, ведь наличие в этой таблице у класса 2 реализации метода из класса 1 нам вовсе и не нужно?
Зачем потомкам содержать инфу о методах родителя, если суть полиморфизма в вызове методов самих потомков, но никак не родительских.
В каком месте рассуждений я пошел по ложному следу?)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.01.2020, 22:08
Ответы с готовыми решениями:

Про перегрузку функции и Virtual в классах
В общем вообще запутался с этим ООП... Вот есть в классе функция, перегрузка функции даёт возможность этой функции иметь несколько...

Protected abstract virtual base pure virtual private destructor
Хай, all) Вопрос не для начинающих и дурацкий) В разделе для экспертов публиковать не стал, чтобы не засорять его) Наткнулся тут на...

Error: Incompatible types: got "Dynamic Array Of reccopyTimeBoxMaxY" expected "Dynamic Array
Операторы перезагрузки есть operator:=(rhs1: recTimeBoxMaxY):reccopyTimeBoxMaxY; begin with Result do begin maxY := rhs1.maxY; ...

8
 Аватар для Arcor
5709 / 2300 / 466
Регистрация: 20.11.2009
Сообщений: 7,721
Записей в блоге: 1
14.01.2020, 23:13
он не отменяет его в 3, об этом даже пишет компилятор как предупреждение, что этот метод уже виртуальный от класса с2. далее lc имеет тип с1, на ее базе вы создаете экземпляр класса с4, в с4 будет явно переопределено все, что иерархия знает о с1, так как дальнейшая реализация не известна еще. во втором классе если вы используете override + inherited, то вы наследуете в с2 все из с1 + дополняете базовый, естественно если вы и в 3 переопределяете, то наследуется все из 2, а 2 из 1 уже
1
17 / 14 / 3
Регистрация: 21.03.2017
Сообщений: 155
15.01.2020, 00:36  [ТС]
Цитата Сообщение от Arcor Посмотреть сообщение
он не отменяет его в 3, об этом даже пишет компилятор как предупреждение, что этот метод уже виртуальный от класса с2.
Ну а тогда почему не вызывается метод класса c3, если он уже виртуальный и компилятор знает об этом, то и в таблице он есть?
Цитата Сообщение от Arcor Посмотреть сообщение
в с4 будет явно переопределено все, что иерархия знает о с1, так как дальнейшая реализация не известна еще.
бррр, не понял, в c4 ничего же не переопределяется, там наследуется от родителя (c3). А он переопределяет метод m.
0
Модератор
4115 / 2347 / 807
Регистрация: 15.11.2015
Сообщений: 9,352
15.01.2020, 01:03
Цитата Сообщение от Алексеич Посмотреть сообщение
Ну а тогда почему не вызывается метод класса c3, если он уже виртуальный и компилятор знает об этом, то и в таблице он есть?
Так в c3 объявлен новый метод с именем m, он уже другой. А объект lc объявлен типа c1, вот метод m и берётся из c1, в котором он перекрыт методом из c2, поэтому срабатывает метод из c2, потому, что сам объект создан как c4.
1
 Аватар для Arcor
5709 / 2300 / 466
Регистрация: 20.11.2009
Сообщений: 7,721
Записей в блоге: 1
15.01.2020, 01:29
Цитата Сообщение от Алексеич Посмотреть сообщение
бррр, не понял, в c4 ничего же не переопределяется, там наследуется от родителя (c3). А он переопределяет метод m.
Сама переменная какого типа?

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

базовый класс автомобиль
у автомобиля 4 колеса, руль, коробка передач на 3 скорости,
далее делаем автомобиль на базе этого с коробкой на 4 скорости, пусть будет авто "Жигули"
далее взасовываем доп вал в коробку с парой шестеренок олучили коробку скоростей на 5 скоростей, осталась база та же "Жигули"

желаем теперь жугуль с уже 5 скоростями который и едем на первый завод, на базовый и создаем на базе его желаемый авто с апгрейдами, а их то там не существует еще, максимум что получим жигуль с тремя скоростями и базовой комплектации,

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

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

по крайней мере все классы что я не писал, работали и вели себя именно таким макаром, как я описал, писал с опыта, а не из умных книжек

для полнопонимания надо пример "потолще" чуток написать, чтобы разобрать, что в базовом есть и чего там еще нет
1
Модератор
4115 / 2347 / 807
Регистрация: 15.11.2015
Сообщений: 9,352
15.01.2020, 09:24
В продолжение аналогии. Сделали авто с КПП с 3 передачами и водителя научили пользоваться этой КПП. Потом на его базе сделали авто с дополнительной коробкой и посадили за руль прежнего водителя, он не знает про новую коробку и пользуется только первой КПП с 4 передачами.
1
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
15.01.2020, 10:36
тоже недавно разбирался немного с этим вопросом
http://delphithink.blogspot.co... rtual.html
...когда мы объявляем в родительском классе метод как virtual, при создании потомка этого класса для него (потомка) так же будет создан этот метод в таблице методов в памяти. Это хорошо если данный метод перекрыт в потомке и нам в любом случае он необходим в памяти. А если метод не перекрыт? Зачем нам идентичная копия метода? А если у нас реализована цепочка наследования из 10 классов и только в одном из наследников этот метод перекрыт, то зачем нам создавать 10 копий одного и того же?
...при объявлении в классе метода как virtual, в каждом наследнике этого класса будет создана копия этого метода вне зависимости от того перекрыт этот метод или нет. Что нам это дает? Скорость вызова. Каждый класс имеет свою копию метода и может быстро его вызвать, не тревожа при этом своего родителя, родителя своего родителя и так далее по цепочке. Минус - занимаемая память.
Если же мы объявим в родительском классе метод как dynamic, то он не будет создаваться в наследниках, если наследники его не перекрывают. Таким образом, даже если у нас реализована цепочка наследования из 10 классов, такой метод будет в памяти только в одном экземпляре. Что нам это дает? Экономия памяти. Минус - скорость вызова.
Что мы имеем в итоге?
Если у вас длинная цепочка наследования и метод, который редко вызывается, используйте dynamic. Этим вы сэкономите память в ущерб скорости в вызова, что на редко вызываемых методах будет не существенно. Именно по этой причине большинство методов в VCL объявлены как dynamic.
Если у вас длинная цепочка наследования и метод, который вызывается часто, оценивайте необходимость быстрого вызова. Если это не критично, используйте dynamic. Если быстрый вызов важен несмотря на занимаемую память, используйте virtual.
Если у вас не большая цепочка наследования, используйте virtual. Экономия памяти при использовании dynamic в таком случае будет минимальна.
2
17 / 14 / 3
Регистрация: 21.03.2017
Сообщений: 155
15.01.2020, 11:36  [ТС]
AzAtom, Arcor, DenNik, спасибо за ответы.
1) Правильно я понял, что в моем примере нужный метод будет искаться только в VMT класса c1, не заходя в VMT классов c2 и т.д.?
2) В этой таблице будет попытка найти метод класса с4, затем с3, но там содержатся только метод m класса с1, и метод класса c2. Метода m класса c3 там нет, он был бы, только если бы он в c3 оверрайдился или вообще не упоминался.
И если бы метод m в с3 не упоминался, то в VMT класса c1 он бы тоже был, а в DMT его бы не было и пришлось бы программе лезть в DMT класса c2, а потом уже найти его в DMT класса с3...
Так правильно?
0
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
15.01.2020, 12:18
на мой взгляд, виртуализировать override-метод - как-то некомильфо. Зачем это? в исходниках VCL такого нет и если рассуждать логически, смысла делать это нет. Как это будет работать, непонятно, поэтому не делай так и не задавайся пустыми вопросами
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.01.2020, 12:18
Помогаю со студенческими работами здесь

Incompatible type for arg no. 3: Got "Dynamic Array Of Dynamic Array Of LongInt", expected "AnsiString"
Массив объявлен так arraygrid: array of array of array of array of array of integer; и вот эта строка StringGrid1.Cells:=arraygrid;...

И снова про PopupMenu (было про длину, теперь про ширину)
Добавляем в пустое PopupMenu несколько пунктов динамически (шириной, например, до 50 символов). Отображаем его – всё нормально. Затем...

Dynamic property
Здраствуйте! У меня на форме есть 2 элемента comboBox1 и label1. В комбобоксе 2 значения для выбора(1212 и 1313). Необходимо чтобы в...

Dynamic Tables
Раз уже пошла речь о java, то и я вставлю свои 5 копеек :blink: Вот пример Посмотреть вложение pack.zip

Dynamic SQL
Привет,господа разработчики. Подскажите пожалуйста, можно ли завернуть нечто подобное под fierbird: set term ##; create procedure...


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

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

Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru