1. Заголовок или название темы должно быть информативным ! 2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code]. 3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК ! 4.НЕ используйте форум для личного общения! 5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!
Объект TObject занимает в памяти 8 байт - сума двух longint, т.е. места для методов не резервируется. Мне интересно, как и где в памяти размещаются методы объектов и куда я обращаюсь, вызывая метод по ссылке - po^.method?
type PTobject=^TObject; TObject=object i,i2:longint; procedure method; end; procedure TObject.method; begin i:=4; end; var mem:longint; po:PTobject; p:pointer; pi:^longint; begin mem:=memavail; new(po); po^.method;{!!!!!!!!!!!!!!!!!!сдесь} p:=po; pi:=p; writeln(pi^); writeln('Difference: ',mem-memavail); readln; end.
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Если бы объект в каждой своей копии хранил код методов, это было бы слишком расточительно, согласись.
Соглашаюсь . Копии объекта только и отличаются своими полями. Но второй вопрос остаётся...
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
+ вспомни, ЧЕМ объект с виртуальными методами отличается от объекта БЕЗ оных...
У него есть поле таблицы виртуальных методов?
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Но я не про это... Отличается объект только со статическими методами тем, что уже на этапе компиляции, а не в Run-Time известно, какой метод и какого объекта будет вызываться, ну, и компилятор, естественно, подставляет адрес этого метода (размещенного в сегменте кода) напрямую...
Очень удобно... И ничего не надо нигде хранить (в смысле, при создании динамического объекта не надо таскать за собой еще адреса и забивать память).
известно, какой метод и какого объекта будет вызываться
Т.е. известно адреса методов в сегменте?
Цитата
подставляет адрес этого метода (размещенного в сегменте кода) напрямую...
Подставляет куда?
volvo, не мог бы ты детально описать, что происходит на уровне памяти в моем коде? Извиняюсь за свою недоходчивость...
Сообщение отредактировано: Bokul -
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
> Подставляет куда? Да уж, действительно придираешься.. Просто не совсем точная формулировка. Ничего не подставляется, адрес сразу в коде. Поскольку для адреса метода не нужно заводить сам объект (экземпляр), то адрес его уже известен на этапе компиляции (линковки, запуска..). Трактуй это просто как обычный код.
--------------------
я - ветер, я северный холодный ветер я час расставанья, я год возвращенья домой
А как же... Конечно известно... Ты никогда не задумывался, почему происходит, например, такая вещь:
type T = object procedure A; procedure B; end;
procedure T.B; begin A; { <--- Почему ЗДЕСЬ компилятор тебе не говорит ничего о НЕописанной процедуре? } end; ...
А потому, что это - Forward declaration, и уже после объявления типа T компилятор знает, где будут располагаться все его методы, ибо количество методов ему известно, параметры известны... Что еще ему надо?
А вызвать метод объекта не описав его тип у тебя не получится по любому, синтаксис языка это запрещает... Поэтому Паскаль, кстати, так быстро компилирует - за один проход... В отличие от С/С++, которые работают за 3-4 прохода...
Цитата
Подставляет куда?
Вместо вызова obj.A; в генерируемый код подставляется CALL {адрес_метода} (ну, в смысле, опкод этого выражения)...
Кажется я начинаю понимать... Нигде не встречал информации о том, где хранится виртуальный метод, где? В куче? Тот же вопрос для VMT? Если бы method в моем коде был виртуальным, что Паскаль бы поставил на место po^.method; при компиляции? Таблица виртуальных методов всегда находится по одному адресу? Т.е. на этапе компиляции мы знаем ее адрес? Где можно почитать о структуре сегмента кода, данных?
Цитата
Что еще ему надо?
Код?
--------------------
Лао-Цзы : Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
Нигде не встречал информации о том, где хранится виртуальный метод, где? В куче?
Виртуальный метод с точки зрения компилятора что, отличается от статического? Он как-то по-другому написан? Для него другой синтаксис? Зачем его хранить ИНАЧЕ чем статический? Он также хранится в сегменте кода, только вот адрес точки входа в него заносится в VMT...
Цитата
Тот же вопрос для VMT?
То же самое... Не нужно ничего лишнего хранить в "куче", поэтому сама VMT хранится в сегменте данных, а экземпляр объекта содержит 16-битный указатель на нее (фактически - смещение в DS). Подробнее - здесь: Глава 17. Внутренний формат объектов