Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как передается у нас объекты в качетсве параметров, по ссылке, по указателю или копия 
:(
    Опции темы
Delphist
Дата 31.7.2008, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Вопрос возник следующий, есть код:
Код

type
 TMyObj = class(TObject) //мой объектк является наследником TOBject
 ...
 end

procedure Foo(Obj: TMyObj);
begin

   Obj.Property1 := 1;
  //и т.д.
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyObj: TMyObj
begin
 
   Foo(MyObj)
end;


1. Возник вопрос как передается MyObj в процедуру Foo - как указатель на объект или передается копия объекта через стек
2. если я напишу вот так - procedure Foo(const Obj: TMyObj);
   Obj.Property1 := 1;
то компилятор ругаться не будет, почему?
3. какая разница между procedure Foo(var Obj: TMyObj); procedure Foo(const Obj: TMyObj); procedure Foo(Obj: TMyObj);




Это сообщение отредактировал(а) Delphist - 31.7.2008, 08:40


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
pseud
Дата 31.7.2008, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

Репутация: 10
Всего: 40



ИМХО - передается указатель на объект.
поетому, компилятору все равно как ты передашь ети цифры.


--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Alexeis
Дата 31.7.2008, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Delphi не умеет копировать объекты. Эта операция потенциально опасная, потому передача всегда будет по ссылке с той лишь разницей что при передаче объекта как var параметра, можно изменить значение той переменной что была передана в функцию, например занулить ее или записать в нее другой объект (напрмер наследника).

Добавлено через 44 секунды
  Кроме того объекты в Delphi в стеке не бывают smile .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
CodeMonkey
Дата 31.7.2008, 10:01 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Любой объект в Delphi - это указатель на блок памяти размером InstanceSize.
Поэтому SizeOf(MyObj) = SizeOf(TMyObj) = 4 <> TMyObj.InstanceSize.
Размер любого объекта - минимум 4 байта (указатель на VMT), не считая сам указатель. Т.е. объект с одним полем типа Integer будет занимать блок памяти 8 байт (4 поле + 4 на VMT) плюс указатель на него - 4 байта, итого - 12 байт.

Поэтому:
procedure Foo(Obj: TMyObj);

Сюда Obj передаётся по значению (как и написано в заголовке процедуры согласно общим принципам языка). Однако, поскольку Obj сам является указателем, то фактически в процедуру передаётся по значению четырёхбайтный указатель. Отсюда видна вся дальнейшая логика.

Что из этого следует? Во первых:

Код
procedure Foo(Obj: TMyObj);
begin
  Obj := nil; // никак не повлияет на MyObj, т.к. указатель передан по значению с копированием
end;

procedure Foo(const Obj: TMyObj); // фактически эквивалентно (Obj: TMyObj), но компилятор искуственно вводит ограничение на модификацию
begin
  Obj := nil; // компилятор запретит модификацию указателя Obj (заметим, это не относится к содержимому памяти, на которую указывает указатель)
end;

procedure Foo(var Obj: TMyObj); // здесь уже передаётся указатель на указатель на объект, т.е. передаётся указатель на объект по ссылке
begin
  Obj := nil; // изменяет MyObj
end;


Легко понять, почему при указании const компилятор даёт присваивать свойства объекта: const относится только к ссылке на блок памяти, но не к самому блоку памяти объекта. 

Кстати, слова "указатель на объект" можно понимать двояко. Во-первых, это может быть в точности ^TMyObj, т.е. фактически "указатель на указатель". Во-вторых, это может быть просто TMyObj, в этом случае под "объектом" просто понимается не блок памяти + указатель, а просто блок памяти.

И ещё по соглашению const и var: часто они идентичны - т.е. данные передаются в процедуру по ссылке. Только для случая const компиятор не даёт их изменять, а для var - разрешает. Однако есть отличия для случая, когда данные имеют размер 4 байта и меньше. В этом случае нет смысла передавать их по ссылке (сама ссылка занимает места больше чем данные), поэтому в этом случае const данные передаются по значению. var-данные, разумеется, в этом случае передаются по ссылке - иначе их нельзя было бы модифицировать.

Добавлено через 1 минуту и 57 секунд
Цитата(Alexeis @  31.7.2008,  09:57 Найти цитируемый пост)
Кроме того объекты в Delphi в стеке не бывают

Уточню smile
Смотря что понимать под объектом. Если собственно данные объекта - то да, никогда не бывают. Если же объект Delphi в строгом пониманиии этого слова (как указатель) - то очень часть они хранятся именно в стеке.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Delphist
Дата 31.7.2008, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(CodeMonkey @  31.7.2008,  11:01 Найти цитируемый пост)
Кроме того объекты в Delphi в стеке не бывают

А в С++ бывают как ни странно


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Alexeis
Дата 31.7.2008, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Delphist @  31.7.2008,  09:47 Найти цитируемый пост)
А в С++ бывают как ни странно 

  В C++ еще и AV частенько появляются по неосторожности smile и порча чужой памяти и затирание служебных данных и еще многа многа других детских неожиданностей  smile .



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
CodeMonkey
Дата 31.7.2008, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Delphist @  31.7.2008,  10:47 Найти цитируемый пост)
А в С++ бывают как ни странно

И что с того? Это к чему вообще?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Delphist
Дата 31.7.2008, 12:41 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(CodeMonkey @  31.7.2008,  12:54 Найти цитируемый пост)
И что с того? Это к чему вообще? 

Эт к тому, что почему этого Borland не сделал для своего компилятора

Это сообщение отредактировал(а) Delphist - 31.7.2008, 12:42


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
CodeMonkey
Дата 31.7.2008, 13:30 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Цитата(Delphist @  31.7.2008,  12:41 Найти цитируемый пост)
почему этого Borland не сделал для своего компилятора

Потому что это не нужно.

Кроме того, как это не сделал? Сделал. 
Перекройте NewInstance/FreeInstance и размещайте объекты хоть в shared memory.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0548 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.