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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Указатели на методы 
V
    Опции темы
Christoph
Дата 26.1.2009, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



В чем смысл указателей на методы, в книге написано "...один класс содержит указатель на метод, который связан с методом другого класса". Не понимаю этих слов  smile 
И не понимаю как это происходит в примере
Вот пример:

Код

type
  TNotifyEvent=procedure (sender: TObject) of object;
type
  TScrollBar=class(TWinControl)
  private
   FOnchange: TNotifyEvent;
 protected
   procedure Change; dynamic;
end;
procedure TScrollBar.Change;
begin
  if Assigned(FOnchange) then
    FOnChange(self);
end;
 type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    ScrollBar1: TScrollBar;
    procedure ScrollBar1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
ListBox1.Columns:=ScrollBar1.Position;
end;

end.


Можете дать некоторые разъяснения по этой теме, спасибо


--------------------
user posted image
PM MAIL ICQ   Вверх
bems
Дата 26.1.2009, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



ну и что не ясно?
FOnchange это указатель на метод типа TNotifyEvent
Скролл бар проверяет ссылается ли этот указаитель на какой-нить метод, и если да - вызывает этот метод. 
В примере явно не указано (но подразумевается) что FOnchange указывает на TForm1.ScrollBar1Change
Таким образом скроллбар оповещает форму об изменениях. 

Все события которые ты видишь в инспекторе объектов это свойства типа "указатель на метод". когда ты в инспекторе объектов назначаешь обработчик события, это значит что при создании формы свойству-событию будет присвоен указатель на твой метод. можно делать и явно:
Код

ScrollBar1.FOnchange:=TForm1.ScrollBar1Change
эта строчка должна показать суть, она не заработает потому что FOnchange - приватное поле
В основном для событий обычно есть такое приватное поле и свойство, дающее доступ к нему:
Код
TScrollBar=class(TWinControl)
  private
   FOnchange: TNotifyEvent;
 protected
   procedure Change; dynamic;
 published
   property OnChange:TNotifyEvent read FOnChange write FOnChange;
end;



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Christoph
Дата 26.1.2009, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



Если не тяжело то напиши небольшой пример, что б понять что представялет собой указатель на метод, просто из 1 примера, не понятно...

И еще как такое возможно FOnChange(Self) - это же свойство и тут в скобках параметр?!
И для чего нужны укзатели на методы так и не понял :(



--------------------
user posted image
PM MAIL ICQ   Вверх
bems
Дата 26.1.2009, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(Christoph @  26.1.2009,  23:00 Найти цитируемый пост)
И еще как такое возможно FOnChange(Self) - это же свойство и тут в скобках параметр?!

это вызов метода, на который указывает указатель  FOnChange

Цитата(Christoph @  26.1.2009,  23:00 Найти цитируемый пост)
И для чего нужны укзатели на методы так и не понял :(

ну я ж написал - например для событий


Цитата(Christoph @  26.1.2009,  23:00 Найти цитируемый пост)
Если не тяжело то напиши небольшой пример, что б понять что представялет собой указатель на метод
указатель на метод это что-то объявленное так:
Код

TNotifyEvent=procedure (sender: TObject) of object;
если убрать  of object то будет указатель на просто процедура (а не метод объекта)



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Christoph
Дата 26.1.2009, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



### нифика не вкуриваю  smile  ладно буду биться....


--------------------
user posted image
PM MAIL ICQ   Вверх
Bose
  Дата 26.1.2009, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 8
Всего: 51



Цитата(bems @  26.1.2009,  21:21 Найти цитируемый пост)
ScrollBar1.FOnchange:=TForm1.ScrollBar1Change


ScrollBar1.FOnchange:=Form1.ScrollBar1Change


Christoph, ты компоненты используешь? События у компонентов используешь?
Вот события как раз и являются указателем на метод. Событие в любом компоненте объявлено как указатель на обработчик события, который является методом другого класса. Когда именно должен вызваться обработчик события определяет сам компонент, но при этом компонент не ничего знает о том какому классу принадлежит этот обработчик.

Положи на форму кнопку. Когда ты в Design-time присвоишь кнопке обработчик события, например OnClick, Delphi добавит к форме новый метод, который будет называться Button1OnClick(Sender). И когда ты запустишь программу, то получится, что когда ты кликнешь по кнопке, кнопка вызовет метод формы Button1OnClick(self). Так как обработчик события является членом другого класса(в нашем примере формы), то ему(обработчику) нужно как-то сообщить о том, кто его(обработчик) вызвал. Для этого в событие передаётся ссылка на вызвавшее событие класс(Self), а обработчик его обрабатывает как Sender. 

PM MAIL WWW Skype   Вверх
Christoph
Дата 27.1.2009, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



спасибо Bose, буду вчитываться в пост, тут еще инфы в справке надыбал, буду готовить вопросы  smile 


--------------------
user posted image
PM MAIL ICQ   Вверх
Christoph
Дата 27.1.2009, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



Это получается что событие это указатель на метод, и это метод описываю сам, и когда возникает событие, вызывается мой метод? так?

И еще событие это свойства, только внутренние поле у них хранит указатель на метод, если ошибаюсь то поправте
например если я кинул на форму кнопку, и создал обработчик события OnClick, то во время запуска происходит вот это?
Код

Button1.OnClick:=Form1.Button1Click

Откуда Делфи знает, что отобразить в Инспекторе объектов, что отобразить в Properties а что в Event? Я думаю,  отбор идет свойствам, у который тип является методом, могу и ошибаться

Это сообщение отредактировал(а) Christoph - 27.1.2009, 19:18


--------------------
user posted image
PM MAIL ICQ   Вверх
MetalFan
Дата 27.1.2009, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



тут надо учитывать, что под понятием "указатель на метод" на самом деле прячется 8ми байтовая запись с двумя указателями...
т.е. нельзя написать:
Код

var
  lPointer: poitner;
begin
  lPointer := @lSomeClassInstance.SomeMethod;

но можно:
Код

type
  TSomeMethodType = procedure of object;
var
  lMethod: TSomeMethodType;
begin
  lMethod:= lSomeClassInstance.SomeMethod;



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Bose
Дата 27.1.2009, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 8
Всего: 51



Цитата(MetalFan @  27.1.2009,  18:32 Найти цитируемый пост)
тут надо учитывать, что под понятием "указатель на метод" на самом деле прячется 8ми байтовая запись с двумя указателями...

Точно! 

Тогда имхо лучше вместо "указатель на метод" использовать "процедурный тип"(procedural type), чтобы асбтрагироваться от деталей реализации. 

Цитата(Christoph @  27.1.2009,  17:40 Найти цитируемый пост)
Это получается что событие это указатель на метод, и это метод описываю сам, и когда возникает событие, вызывается мой метод? так?

Да. 

Точнее: событие - это свойство(property) у класса. Свойство - процедурного типа.

Цитата(Christoph @  27.1.2009,  17:40 Найти цитируемый пост)

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

Лучше абстрагироваться от использования термина "указатель". Это свойство процедурного типа. Свойства могут быть любых типов, как integer, string, enumeration, так и record, и класса, так и процедурного типа.

Цитата(Christoph @  27.1.2009,  17:40 Найти цитируемый пост)

например если я кинул на форму кнопку, и создал обработчик события OnClick, то во время запуска происходит вот это?
Код

Button1.OnClick:=Form1.Button1Click


Да.

Цитата(Christoph @  27.1.2009,  17:40 Найти цитируемый пост)
Откуда Делфи знает, что отобразить в Инспекторе объектов, что отобразить в Properties а что в Event? Я думаю,  отбор идет свойствам, у который тип является методом, могу и ошибаться

Я не знаю. Может быть так.

Это сообщение отредактировал(а) Bose - 27.1.2009, 19:56
PM MAIL WWW Skype   Вверх
Christoph
Дата 27.1.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



Спасибо 
Bose, MetalFan, bems, ребята огромное спасибо что помогли разобраться, поставил бы всем по +, но помоему можно ставить раз в сутки) Так что не обижайтесь) если плюсик дам 
Bose, и еще раз спасибо!

Тему не закрываю, хотел бы еще уточнить маленькую подробность, стандартная диспетчеризация событий - это стандартная обработка событий, так вот вопросом в чем, зачем обработчка события по умолчанию?ну пустой обработчик события, так и ничего не делает...вот этот момент не понимаю. Рассматривал примеры, метод диспечтчеризации как то связан с событием? В виде кода это не увидел, или быть может опять неявно связывается метод диспетчеризации и событие? Спасибо smile 


--------------------
user posted image
PM MAIL ICQ   Вверх
bems
Дата 27.1.2009, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(Christoph @  27.1.2009,  22:27 Найти цитируемый пост)
стандартная диспетчеризация событий
не путаешь с сообщениями?



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Bose
Дата 27.1.2009, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 8
Всего: 51



Цитата(Christoph @  27.1.2009,  21:27 Найти цитируемый пост)
стандартная диспетчеризация событий

Даже не представляю себе, что это такое. Что это такое? 

PM MAIL WWW Skype   Вверх
Christoph
Дата 28.1.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



Цитирую с книги: "Методы диспетчеризации несут отвественность за исполнение метода, на который ссылается указатель на метод события..." И небольшой пример:

Код

type
  TBeepButton=class(TButton)
  protected
    procedure Click; override;  \\ метод диспетчерризации
end;

procedure TBeepButton.Click;
begin
  inherited Click;           \\ Диспетчеризация по умолчанию - обработчик, определенный пользователем, пользовательская обработка происходит здесь
  MesageBeep(0);
end;


Не понимаю зачем нужен обработчик события по умолчанию и есть ли какая то явная свзязь, с событиями?


--------------------
user posted image
PM MAIL ICQ   Вверх
MetalFan
Дата 28.1.2009, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



что-то какая-то мутная в плане терминологии книжка...
Знаю понятие "диспетчеризация сообщений"...
но при чем тут конкретная реализация (перекрытие виртуального метода предка и его вызов) и диспетчеризация


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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