Форум: "Основная";
Текущий архив: 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