Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];

Вниз

Как в методе получить указатель на перем-ю, которая вызвала метод   Найти похожие ветки 

 
Mishenka   (2004-03-31 00:08) [0]

Есть class у которого есть метод. А также есть переменные с типом этого класса. Как в этом методе получить указатель на переменную, которая вызвала этот метод?


 
eLVik ©   (2004-03-31 00:30) [1]

self
А тебе это зачем?


 
Mishenka   (2004-03-31 00:56) [2]

Да я вот так и написал Self. Но при попытке обратиться к одному из свойств Self вызывает ошибку EAccessViolation :(((


 
Defunct ©   (2004-03-31 01:00) [3]

Self это малость не то. Self указывает на объект с полями которого работает текущий метод. А определить кто вызвал этот метод можно только в том случае, если передать указатель на вызывающий объект в параметрах метода. Обычно это Sender:TObject.

А далее уже в теле метода смотреть:

If Sender is (какой-то класс) Then Sender as (какой-то класс) Do


 
Defunct ©   (2004-03-31 01:04) [4]

> Но при попытке обратиться к одному из свойств Self вызывает ошибку EAccessViolation :(((

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


 
Mishenka   (2004-03-31 01:55) [5]


> Defunct ©   (31.03.04 01:04) [4]
> А вот это уже совсем интересно. Если возникает ошибка только
> при обращении к однону из свойств, значит неверно описано
> свойство.

Ну просто только к одному и обращался :)))


> If Sender is (какой-то класс) Then Sender as (какой-то класс)Do

А если имя класса неизвестно, а известно лишь что это один из потомков данного класса, то можно ли обойтись без перебора всех классов?


 
Rouse_ ©   (2004-03-31 02:13) [6]

> Как в этом методе получить указатель на переменную, которая
> вызвала этот метод?

Банально, переменная не может вызвать метод (если не опускаться до полиморфии...)

> Если возникает ошибка только при обращении к однону из свойств,
> значит неверно описано свойство

Также может быть неверно описан сам объект... (как раз таки пика в сторону оператора AS)

> А если имя класса неизвестно, а известно лишь что это один
> из потомков данного класса, то можно ли обойтись без перебора
> всех классов?

Без вызова методов наследников можно...


 
Mishenka   (2004-03-31 02:23) [7]


> Rouse_
> Без вызова методов наследников можно...

А как?


 
Германн ©   (2004-03-31 02:42) [8]

Если не известен точно класс, на экземпляр которого указывает данный указатель, но известно точно, что это потомок некоего класса TSomeClass, то можно обратиться к любому методу класса предка (TSomeClass). Причем если данный метод был overridden в данном потомке или в цепочке потомков, то будет вызван последний вариант метода. Но если у известного вам класса (TSomeClass) такого метода не было, поскольку он добавлен в потомках, то без перебора уже никак.


 
Mishenka   (2004-03-31 02:48) [9]


> Германн ©   (31.03.04 02:42) [8]

Это всё замечательно, только  там где Sender as как это всё написать и каким классом обозвать. Если писать класс родителя, то выдаёт ошибку.


 
Германн ©   (2004-03-31 03:09) [10]

2 Mishenka   (31.03.04 02:48) [9]
Во-первых какую ошибку?
Во-вторых, лучше бы привести фрагмент кода, а не ограничиваться общими словами, которые мы можем понимать по-разному.


 
Mishenka   (2004-03-31 03:37) [11]

Ошибка EInvalidCast тобишь недопустимое преобразование типов с помощью оператора as...


 
Германн ©   (2004-03-31 03:52) [12]

А где "фрагмент кода"?
EInvalidCast - действительно та самая ошибка, но где и как она возникает?
Без кода - это "пойди туда, не знаю куда. принеси то, не знаю что"!


 
Mishenka   (2004-03-31 04:23) [13]

Лови код:

TMainClass=class(TObject)
   Width,Height:Integer;
   procedure GetWH(Sender: TObject);
   function GetName:string; virtual; abstract;

 end;

TClassA=class(TMainClass)
   propA:Integer;
   function GetName:string; override;
 end;

 TClassB=class(TMainClass)
   propB:Integer;
   function GetName:string; override;
 end;

 TClassC=class(TMainClass)
   propC:Integer;
   function GetName:string; override;
 end;

...

procedure TMainClass.GetWH(Sender: TObject);
var Ob:TMainClass;
begin
  Ob:=Sender as Sender.ClassName; {здесь происходит EInvalidCast
    with Form2 do
    begin
       Edit1.Clear;
       Edit2.Clear;
       ShowModal;
       if ModalResult=mrOk then
       begin
            Form1.ListBox1.Items.AddObject(Sender.GetName,Ob);
       end;
    end;
end;

function TClassA.GetName:string;
begin
    GetName:="A";
end;

function TClassB.GetName:string;
begin
    GetName:="B";
end;

function TClassC.GetName:string;
begin
    GetName:="C";
end;



 
ЮЮ ©   (2004-03-31 06:56) [14]

>Sender as Sender.ClassName

ClassName - это стринг
Ob := TMainClass(Sender);

А проще переписать сам TMainClass так:

TMainClass = class;
TMainClass = class(TObject)
  Width,Height:Integer;
  procedure GetWH(Sender: TMainClass);
  function GetName:string; virtual; abstract;
end;


 
ЮЮ ©   (2004-03-31 06:59) [15]

P.S.
>Form1.ListBox1.Items.AddObject(Sender.GetName,Ob);
Form1.ListBox1.Items.AddObject(Ob.GetName,Ob);


 
Гаврила   (2004-03-31 09:25) [16]

Не совсем понятный, и странный код
а где вызывается TMainClass.GetWH?
И как ? И что передается в качестве параметра Sender ?

ТО есть я правильно понял, что параметром в метод GetWH передается другой экземпляр класса TMainClass(или потомка) ?
В противном случае параметр Sender явно лишний.

Приведи код вызова метода


 
Palladin ©   (2004-03-31 09:28) [17]

Sender as FindClass(Sender.ClassName)

перед этим искомый класс должен быть зарегистрирован RegisterClass


 
Palladin ©   (2004-03-31 09:44) [18]

:) здорово я пошутил :)

ответ не принимать в расчет ибо подобное приведение ни к чему не приведет


 
Mishenka   (2004-03-31 16:31) [19]

Ну вот вам код вызова метода:


procedure TForm1.Button1Click(Sender: TObject);
var A:TClassA;
begin
    A.GetWH(A);
end;

procedure TForm1.Button2Click(Sender: TObject);
var B:TClassB;
begin
    B.GetWH(B);
end;

procedure TForm1.Button3Click(Sender: TObject);
var C:TClassC;
begin
    C.GetWH(C);
end;


 
Mishenka   (2004-03-31 22:40) [20]

Ну что? Есть идеи?


 
ЮЮ ©   (2004-04-01 03:20) [21]

Убрать параметр совсем

Form1.ListBox1.Items.AddObject(GetName, Self);

P.S. Использование Form1 и Form2 в коде метода TMainClass, IMHO, не очень уместно


 
LexusR ©   (2004-04-01 06:17) [22]


procedure TMainClass.GetWH(Sender: TObject);
begin
   with TForm2.Create(nil) do
   begin
      Edit1.Clear;
      Edit2.Clear;
      ShowModal;
      if ModalResult=mrOk then
      begin
           Self.Width  := StrToInt(Edit1.text);
           Self.Height := StrToInt(Edit2.Text);
           Form1.ListBox1.Items.AddObject(Self.GetName,Self);
      end;
      Free;
   end;
end;
......
procedure TForm1.Button1Click(Sender: TObject);
var A:TClassA;
begin
   A := TClassA.Create;
   A.GetWH(A);
   A.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var B:TClassB;
begin
   B := TClassB.Create;
   B.GetWH(B);
   B.Free;
end;

procedure TForm1.Button3Click(Sender: TObject);
var C:TClassC;
begin
   C := TClassC.Create;
   C.GetWH(C);
   C.Free;
end;



 
LexusR ©   (2004-04-01 06:18) [23]

и как сказал ЮЮ  параметр Sender лишний


 
Defunct ©   (2004-04-01 08:54) [24]

Что-то я не понял в чем прикол.
Как первоначальный вопрос Mishenka   (31.03.04 00:08), стыкуется с этим кодом: Mishenka   (31.03.04 16:31) [19]?

Зачем вам вызывающий объект? Ведь в данном случае метод вызывает объект класса TForm1.

Ну ладно умом россию не понять.


 
Mishenka   (2004-04-01 22:41) [25]


> LexusR ©   (01.04.04 06:17) [22]

Круто! Так всё работает! Спасибо.
Только у меня ещё одна фигня получилась.
Нужно чтобы по DblClick на ListBox выводилось имя объекта.
Пишу:

procedure TForm1.ListBox1DblClick(Sender: TObject);
var ClassMain:TMainClass;
begin
    with ListBox1 do
    ClassMain:=Items.Objects[ItemIndex] as TMainClass;
    ShowMessage(ClassMain.ClassName);
end;


Опять вылазит ошибка EInvalidCast. Чё-то я опять торможу...


 
Гаврила   (2004-04-01 23:02) [26]

>>LexusR ©   (01.04.04 06:17) [22]

Добавили Self в объекты строкового списка, а потом этот самый Self грохнули (см вызов метода GetWH)

так нельзя

вообще, (к автору ветки) - организуйте структуру кдассов - вызовов по другому, то, что тут представлено - это чекрез одно место.
скорее всего это должны быть методы формы, а не доп. классов

Блин !!!! А создать экземпляры классов ?
разумеется, какое то методы можно вызывать и не создавая экземпляры (Self будет равен nil, пример - метjд Free )
Но это отночится только к статическим методам, не использующим поля-свойства


 
Гаврила   (2004-04-01 23:07) [27]

Последний абзац  моего поста [26] прошу не рассматривать, я его написал прежде чем увидел ответ [22]

автору
если вы настаиваете на именно такой  организации, не разрушайте экземпляры TClassA (и прочих в случае показа модальной формы с результатом MrOk). При этои не забудьте разрушить их перед очисткой Form1.ListBox1.Items


 
Гаврила   (2004-04-01 23:09) [28]

function TMainClass.GetWH(Sender: TObject): Boolean;
begin
  with TForm2.Create(nil) do
  begin
     Edit1.Clear;
     Edit2.Clear;
(Result:=ShowModal = MrOk);
     
     if Result then
     begin
          Self.Width  := StrToInt(Edit1.text);
          Self.Height := StrToInt(Edit2.Text);
          Form1.ListBox1.Items.AddObject(Self.GetName,Self);
     end;
     Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var A:TClassA;
begin
  A := TClassA.Create;
  if not A.GetWH(A) then
    A.Free;
end;


 
Mishenka   (2004-04-02 14:50) [29]

Это всё зачмечательно, только я так и не понял что делать в DblClick:
procedure TForm1.ListBox1DblClick(Sender: TObject);
var ClassMain:TMainClass;
begin
   with ListBox1 do
   ClassMain:=Items.Objects[ItemIndex] as TMainClass;
   ShowMessage(ClassMain.ClassName);
end;

выдаёт ошибку EInvalidCast и всё тут.


 
Mishenka   (2004-04-02 21:16) [30]

Может всё-таки есть какие-нибудь предложения?


 
Mishenka   (2004-04-02 21:16) [31]

Может всё-таки есть какие-нибудь предложения?


 
Defunct ©   (2004-04-02 23:23) [32]

Вот для пущей наглядности:

 TMainClass = class(TObject)
   Width,Height:Integer;
   function GetName:string; virtual; abstract;
 End;

 TClassA=class(TMainClass)
   propA:Integer;
   function GetName:string; override;
 end;

TClassB=class(TMainClass)
  propB:Integer;
  function GetName:string; override;
end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

Function TClassA.GetName;
Begin
 Result := "Class A";
End;

Function TClassB.GetName;
Begin
 Result := "Class B";
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
 ListBox1.AddItem("Class A", TClassA.Create);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 ListBox1.AddItem("Class B", TClassB.Create);
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
Var MainClass: TMainClass;
begin
 MainClass := ListBox1.Items.Objects[ListBox1.ItemIndex] as TMainClass;
 ShowMessage(MainClass.GetName);
end;


Никакого EInvalidCast нет.


 
Mishenka   (2004-04-04 17:07) [33]

Такдействительно ошибки нет, но нужночтобы объекты добавлялись через метод один метод, а не каждый в своей кнопке. Просто не пому, почему тут всё работает, а там нет ...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.04.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.031 c
1-1079839256
PIA
2004-03-21 06:20
2004.04.18
Запуск программ написанных в Delphi 8


7-1077017287
Kremen
2004-02-17 14:28
2004.04.18
МАС-адрес


6-1076263145
Захар
2004-02-08 20:59
2004.04.18
Как построить почтовый (SMTP & POP3) сервер?


9-1066560657
ArtemHD
2003-10-19 14:50
2004.04.18
Как легче сделать уровни и модели для GLScene


9-1054574071
Zew
2003-06-02 21:14
2004.04.18
Деньги в игре





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский