Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.11.2010, 08:56   #1
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию Вопрос по классам, обработчикам событий...

Начал изучать классы в C++, столкнулся с понятиями слота и сигнала. Прочитал про connect, SIGNAL и SLOT, и стало интересно, как было все реализовано в Delphi, где я раньше кодил и уютнее себя чувствал
Первый пример, который я решил разобрать - это событие Button1.OnClick.
Я так понимаю, в Delphi C-подобный код создается автоматически:
Код:
connect(Button1, SIGNAL(OnClick()), Form1, SLOT(Button1Click(TObject)))
Просто этот код Delphi пишет автоматически и мы его не видем. Далее, почитав, что при вызове connect SLOT может принимать параметры только из SIGNAL'а, я решил, что connect Delphi пишет так:
Код:
connect(Button1, SIGNAL(OnClick(TObject)), Form1, SLOT(Button1Click(TObject)))
Вот. Далее, я решил поэксперементировать, а какого черта Button1Click должен принимать параметр TObject? Ведь, он может принимать не все параметры из SIGNAL'а. Решил написать код:
Код:
type
  TForm1 = class(TForm)
	Button1: TButton;
	procedure Button1Click;
  private
	{ Private declarations }
  public
	{ Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click;
begin
  ShowMessage('1');
end;

end.
На что получил ругательство Delphi (The Button1Click method referenced by Button1.OnClick has an incompatible parameter list. Remove the reference? - No), но тем не менее программу он всё равно скомпилировал и запустил. Далее, я рассуждал так. На лишние параметры в SLOT'е Delphi ругается - правильно делает. А на их недостаток - тоже. Странно. И я решил, что Delphi в обработчик события всегда будет передавать Sender'а, вызвавшего это событие, например, чтобы выполнять разный код при различных Sender'ах, или не выполнять ничего при определённых Sender'ах.
Тогда я решил создать свой класс, сделать событие, и привязать обработчик к этому событию. Если бы он ругался бы на обработчик без параметров, а на обработчик с параметром TObject - нет, тогда всё ясно, Delphi всегда передает в обработчик Sender'а, независимо ни от чего другого. То есть, даже если SIGNAL будет без параметров. Однако, я такое только попытался сделать, и тут же возникли проблемы. Вот код, при нажатии на кнопку вылетает AccessViolation, из-за чего он возникает и как его исправить - я не знаю. Код:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyObj = class(TObject) //Свой класс
	summ: integer;
	procedure sum(a, b: integer);
  end;
  TForm1 = class(TForm)
	Button1: TButton;
	MyObj: TMyObj;
	procedure sumsum(Sender: TObject);
	procedure Button1Click(Sender: TObject);
  private
	{ Private declarations }
  public
	{ Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

/* Какое-то событие, которое в будущем хочу использовать как сигнал. Знаю, что оно
не должно иметь тела кода, но тем не менее, оно даже сейчас пока не работает. :( */
procedure TMyObj.sum(a, b: integer);
begin
  summ := a + b;
end;

/* Обработчик будущего события. Чтобы убедиться, что Sender передается всегда, независимо от параметров
функции-сигнала. */
procedure TForm1.sumsum(Sender: TObject);
begin
  ShowMessage(IntToStr((Sender as TMyObj).summ));
end;

/* Нажатием на кнопку изначально хотел породить сигнал, но потом пришёл к еще одной проблеме -
ошибка AccessViolation, хотя не понимаю, откуда она возникает, вроде же все правильно?
Если написать Button1 и какое-то свойство/метод - всё работает, а если MyObj - то никак.
Думал, проблема в том, что прежде надо создать объект, но видимо, тоже не в этом дело. :( */
procedure TForm1.Button1Click(Sender: TObject);
begin
  //Пробовал разные варианты - все равно возникает ошибка :(
  //Form1.MyObj.Create;
  //Form1.MyObj.sum(1, 3);
  Form1.MyObj.summ := 1;
  //Form1.MyObj.Free;
end;

end.
. Собственно, объясните, пожалуста, из-за чего возникает ошибка и как её исправить? А заодно может и найдёте ошибки в моих рассуждениях и избавите от кучи работы, которую я, возможно, делаю впустую.
P.S. Классы начал изучать в C++, потому что в универе мы их проходим. А почему вспомнил про Delphi? Потому что за ним сижу уже 4 года, а за C++ - только полгода, поэтому и интересуюсь, как это устроено в Delphi.

Ааа, может надо писать:
Код:
Form1.MyObj := TMyObj.Create;
?? Тогда, объясните, почему такой вариант не работает:
Код:
Form1.MyObj.Create;
, и чем они различаются?

У нас для оформления кода есть кнопка #. Попрошу ее использовать.

Последний раз редактировалось Stilet; 01.11.2010 в 09:59.
Vadik(R) вне форума Ответить с цитированием
Старый 01.11.2010, 09:42   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

TMyObj.Create; вызывается метод указанного класса TMyObj
Form1.MyObj.Create; вызывается метод конкретного объекта Form1.MyObj.
а он (этот объект) вдобавок еще и не существует ->AccessViolatiuon.
чтобы объект существовал он должен быть создан
Form1.MyObj := TMyObj.Create;
Цитата:
в Delphi, где я раньше кодил и уютнее себя чувствал
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 01.11.2010, 10:01   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Кто-нибудь что-нибудь понял???
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.11.2010, 10:57   #4
Vadik(R)
Пользователь
 
Регистрация: 10.03.2008
Сообщений: 68
По умолчанию

Пока упрощю вопрос:
Почему при задании обработчика событий button1.onClick создается процедура Button1Click(Sender: TObject) именно с таким параметром (процедура имеет именно такой прототип)? Почему если я хочу присвоить обработчик без параметров - делфи ругается?
Vadik(R) вне форума Ответить с цитированием
Старый 01.11.2010, 11:10   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Почему если я хочу присвоить обработчик без параметров - делфи ругается?
Потому что спецификация обработчика такая, и ниче ты с этим не поделаешь.
Не получится присвоить на OnClick обработчик, описанный отличнительно от типа TNotifyEvent
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задача по классам emnm Общие вопросы C/C++ 8 19.10.2010 23:14
Задача по классам Эльдар 18 Общие вопросы C/C++ 3 24.09.2010 00:38
Вопрос по классам делфи и их использованию. Solrainer7 Общие вопросы Delphi 6 12.07.2010 19:16
Вопросы по классам JOFRIF Общие вопросы C/C++ 19 23.08.2009 05:43