Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Теоретические вопросы _ Размещение объекта в памяти

Автор: Bokul 2.12.2006 7:21

Объект 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.


Автор: lapp 2.12.2006 7:46

Если бы объект в каждой своей копии хранил код методов, это было бы слишком расточительно, согласись.

Автор: Bokul 2.12.2006 7:59

Цитата
Если бы объект в каждой своей копии хранил код методов, это было бы слишком расточительно, согласись.

Соглашаюсь smile.gif . Копии объекта только и отличаются своими полями. Но второй вопрос остаётся...

Автор: volvo 2.12.2006 8:05

Цитата
куда я обращаюсь, вызывая метод по ссылке
blink.gif

unit unit_1;
interface

procedure P;

implementation

procedure p;
begin
writeln('just a test...');
end;

end.


uses unit_1;
begin
P; { <--- Куда ты здесь обращаешься? }
end.


+ вспомни, ЧЕМ объект с виртуальными методами отличается от объекта БЕЗ оных... smile.gif

Автор: Bokul 2.12.2006 8:21

Цитата
{ <--- Куда ты здесь обращаешься? }

Не знаю... unsure.gif Куда-то в сегмент кода?
Цитата
+ вспомни, ЧЕМ объект с виртуальными методами отличается от объекта БЕЗ оных...

У него есть поле таблицы виртуальных методов?

Автор: volvo 2.12.2006 8:42

Цитата
У него есть поле таблицы виртуальных методов?
yes2.gif Но я не про это... Отличается объект только со статическими методами тем, что уже на этапе компиляции, а не в Run-Time известно, какой метод и какого объекта будет вызываться, ну, и компилятор, естественно, подставляет адрес этого метода (размещенного в сегменте кода) напрямую...

Очень удобно... И ничего не надо нигде хранить (в смысле, при создании динамического объекта не надо таскать за собой еще адреса и забивать память).

Автор: Bokul 2.12.2006 8:55

Можно чуть-чуть придраться? smile.gif

известно, какой метод и какого объекта будет вызываться

Т.е. известно адреса методов в сегменте?
Цитата
подставляет адрес этого метода (размещенного в сегменте кода) напрямую...

Подставляет куда?

volvo, не мог бы ты детально описать, что происходит на уровне памяти в моем коде? Извиняюсь за свою недоходчивость...

Автор: lapp 2.12.2006 9:01

> Подставляет куда?
Да уж, действительно придираешься.. smile.gif Просто не совсем точная формулировка. Ничего не подставляется, адрес сразу в коде. Поскольку для адреса метода не нужно заводить сам объект (экземпляр), то адрес его уже известен на этапе компиляции (линковки, запуска..). Трактуй это просто как обычный код.

Автор: volvo 2.12.2006 9:08

Цитата
известно адреса методов в сегменте?
А как же... Конечно известно... Ты никогда не задумывался, почему происходит, например, такая вещь:

type
T = object
procedure A;
procedure B;
end;

procedure T.B;
begin
A; { <--- Почему ЗДЕСЬ компилятор тебе не говорит ничего о НЕописанной процедуре? }
end;
...

А потому, что это - Forward declaration, и уже после объявления типа T компилятор знает, где будут располагаться все его методы, ибо количество методов ему известно, параметры известны... Что еще ему надо? smile.gif

А вызвать метод объекта не описав его тип у тебя не получится по любому, синтаксис языка это запрещает... Поэтому Паскаль, кстати, так быстро компилирует - за один проход... В отличие от С/С++, которые работают за 3-4 прохода...

Цитата
Подставляет куда?
Вместо вызова obj.A; в генерируемый код подставляется CALL {адрес_метода} (ну, в смысле, опкод этого выражения)...

Автор: Bokul 2.12.2006 9:41

Кажется я начинаю понимать...
Нигде не встречал информации о том, где хранится виртуальный метод, где? В куче? Тот же вопрос для VMT?
Если бы method в моем коде был виртуальным, что Паскаль бы поставил на место po^.method; при компиляции?
Таблица виртуальных методов всегда находится по одному адресу? Т.е. на этапе компиляции мы знаем ее адрес?
Где можно почитать о структуре сегмента кода, данных?

Цитата
Что еще ему надо?

Код?

Автор: volvo 2.12.2006 17:04

Цитата
Нигде не встречал информации о том, где хранится виртуальный метод, где? В куче?
Виртуальный метод с точки зрения компилятора что, отличается от статического? Он как-то по-другому написан? Для него другой синтаксис? Зачем его хранить ИНАЧЕ чем статический? Он также хранится в сегменте кода, только вот адрес точки входа в него заносится в VMT...

Цитата
Тот же вопрос для VMT?
То же самое... Не нужно ничего лишнего хранить в "куче", поэтому сама VMT хранится в сегменте данных, а экземпляр объекта содержит 16-битный указатель на нее (фактически - смещение в DS). Подробнее - здесь:
http://sizov.boom.ru/books/turbo6/tpash.htm