Вызов процедуры.

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Ответить
Tsuyu
незнакомец
Сообщения: 8
Зарегистрирован: 24.09.2015 15:18:57

Вызов процедуры.

Сообщение Tsuyu »

В чем разница между обычным вызовом и вызовом (по ссылке?) ?
Пример:
Так работает:

Код: Выделить всё

newButton.OnClick := @ChangeTool;

Так не работает:

Код: Выделить всё

newButton.OnClick := ChangeTool;
gvido
постоялец
Сообщения: 188
Зарегистрирован: 28.03.2012 11:35:31

Сообщение gvido »

Tsuyu писал(а):В чем разница между обычным вызовом и вызовом (по ссылке?) ?
Пример:
Так работает:

Код: Выделить всё

newButton.OnClick := @ChangeTool;

Так не работает:

Код: Выделить всё

newButton.OnClick := ChangeTool;

Последний вариант, будет работать в дельфи. Там многое лишнего позволено.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5717
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

Tsuyuя не знаю как определено ChangeTool, но очень похоже, что это не процедура, а ссылка на нее, соответственно, второй вариант и не должен быть верным. Ведь не всегда ссылка ведет на процедуру. она может быть равна и nul.
Tsuyu
незнакомец
Сообщения: 8
Зарегистрирован: 24.09.2015 15:18:57

Сообщение Tsuyu »

Лекс Айрин писал(а):Tsuyuя не знаю как определено ChangeTool, но очень похоже, что это не процедура, а ссылка на нее, соответственно, второй вариант и не должен быть верным. Ведь не всегда ссылка ведет на процедуру. она может быть равна и nul.

Код: Выделить всё

procedure TMainWindow.ChangeTool(Sender: TObject);
begin
  CurToolIndex := (Sender as TSpeedButton).Tag;
end;
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5717
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

Tsuyu, то, что вы указали тело процедуры, а не определение. Вы лучше дайте определение из интерфейсной части. Но, если я правильно понял, что TMainWindow форма, то onClick определяется как:

Код: Выделить всё

property OnClick: TNotifyEvent read FOnClick write FOnClick; 


где

Код: Выделить всё

TNotifyEvent = procedure(Sender: TObject) of object;
FOnClick: TNotifyEvent;


то есть, onClick это, фактически, ссылка на адрес процедуры. ChangeTool же обычная процедура. Следовательно, для приведения их друг к другу, требуется взятие адреса процедуры.
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

Это просто разный синтаксис для одного и того же. Не помню, какой вариант в каком режиме ({$mode delphi}, {$mode objfpc}, {$mode fpc}) работает, но лучше использовать тот, что предполагает @, иначе получается неоднозначность:

Код: Выделить всё

function F: pointer;
var p: pointer;
p := F; // вызов функции или взятие адреса?
        // В C-подобных языках это разрешается обязательностью пустых скобок: p = F — ссылка на функцию, p = F() — вызов.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5717
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

runewalsh писал(а):Это просто разный синтаксис для одного и того же.


Если так считать, то тогда и начинаются проблемы. Человек со временем может перестать понимать где есть ссылка на процедуру/функцию, а где она сама.
Ответить