Форум: "Основная";
Текущий архив: 2003.01.02;
Скачать: [xml.tar.bz2];
ВнизКак создать указатель на обьект внутри метода этого обьекта? Замы Найти похожие ветки
← →
a-leksey (2002-12-14 15:28) [0]Суть вопроса такова... Некоторые обьекты при создании и инициализации должны регестрировать себя в некотором
списке, оставляе там указатель сакми на себя. Так как в нутри метода обьект доступен как Self, я использую @Self,
чтобы создать указатель на обьект, но логично думать, что Self уже, не что иное, как указатель...Вот тут я и запутался.
Как внутри метода создать указатель на обьект и передать его??? Приведение типом не спасло варианты типа
Pointer(Self) или pmy(Self) не помогли..Одним словом указатель на обьект либо не создается, либо теряется...
Если снять ремарки //s2.b:=@s1;, то все работает (а куда оно денется?), но мне нужно создать указатель внутри
метода...как? На примере все упрощено вместо списка переменная и один обьект. Может, кто даст дельный совет?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
pmy = ^my;
my1 = record
b:pmy;
end;
my = class
a:string;
constructor create(lmy1:my1);
destructor destroy;
end;
var
Form1: TForm1;
s1:my;
s2:my1;
implementation
{$R *.DFM}
constructor my.create(lmy1:my1);
begin
inherited create;
lmy1.b:=@self;
end;
destructor my.destroy;
begin
inherited destroy;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
s1:=my.create(s2);
s1.a:="Ok";
//s2.b:=@s1;
ShowMessage(s2.b.a);
end;
end.
← →
Rouse_ (2002-12-14 19:37) [1]Интересная задачка, два часа пришлось ломать голову, дошло до того что пошел по ассемблерному коду трассировкой и вот что выяснил.
s2.b:=@s1; срабатывает, так как уже в самом начале @S1 имеет свой адрес, а @self - возвращает не его, поэтому ногами не пинать плз, вот все что я могу предложить, надеюсь что кто-нибудь из мастеров всеже найдет лучшее решение проблемы:
pmy = ^my;
my1 = record
b: pmy;
end;
my = class
a: string;
constructor create( var lmy1:my1; var lmy2: my);//override;
destructor destroy;
end;
var
Form1: TForm1;
s1:my;
s2, s3:my1;
implementation
{$R *.DFM}
constructor my.create( var lmy1:my1; var lmy2: my);
begin
inherited Create;
//lmy1.b := @Self; //Значение @Self - $0012F3E8, видать адрес с описанием "MY"
lmy1.b := @lmy2;//Реальное значение по адресу - $00454C4C, там находится "S1" (экземпляр класса?)
{asm //Это слишком грубо :(
mov eax, $00454c4c //Но работает
mov [s2], eax //Хотя теже яйца, только вид сбоку
end; }
end;
destructor my.destroy;
begin
inherited destroy;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//S1 с самого начала расположен по адресу $00454C4C
s1:=my.create(s2, s1);
s1.a:="Ok";
ShowMessage(s2.b.a);
end;
Еще раз, просьба ногами не бить, это все что я смог придумать :))
Желаю успехов
← →
Alex Konshin (2002-12-14 20:54) [2]Я напрочь не понял, зачем объявляется pmy, если в Delphi все объектные переменные на самом деле указатели?
Просто в своей record укажи b:my и присваивай потом lmy1.b = Self
Вот как раз-таки record нужно передавать через указатель, иначе у тебя на стеке будет создана копия и именно с ней ты будешь работать.
То есть, окончательно, это будет так:
type pmy1 = ^my1;
constructor my.create(lmy1:pmy1);
begin
inherited create;
lmy1^.b := self;
end;
← →
Polevi (2002-12-16 10:29) [3]и вообще лучше вместо record всегда (ну почти..) использовать class, и не надо никаких @ и ^
← →
VaS (2002-12-16 11:28) [4]А как же память, Polevi? :)
← →
Calm (2002-12-16 11:42) [5]
> VaS © (16.12.02 11:28)
> А как же память, Polevi? :)
А перерахода памяти нет. Если создатать свой класс от TObject, то он не израходует никакой дополнительной памяти (ну может несколько байт)
Вот если объектов очень много (сотни тысяч), тогда, наверное, лучше record
← →
Reindeer Moss Eater (2002-12-16 11:53) [6]unit MyClass;
type
{определение самого класа}
implementation
var
List:TList;
constructor TmyClass.Create;
begin
//все что надо
List.Add(Self);
end;
initialization
List:=TList.Create;
finalization
List.Free;
end.
И абсолютно все экземпляры класса будут в нашем списке.
Или надо что-то другое?
← →
a-leksey (2002-12-16 20:58) [7]Спасибо за советы...
Внатуре все обьекты есть указатели и @self создает двойной указатель, поэтому у мя и не работало... Что нужно создать указатель с адресом лежащим в self new(pmy); pmy^=self;
Чево не пользуюсь стандартными списками - не хочу, видь интересней написать свой.
Почему указатель - просто чисто обьектами не проканает - перекресные ссылки, а использование указателя лишит проблему:
type
ptype1=^type1;
type0 = class
// a:type1; ошибка видб тип еще не обьявлен
a:ptype1;
end;
type1 = class
a:type0;
end;
А вообще спасибо, не ожидал даже... Удивили ...
← →
icWasya (2002-12-17 09:32) [8]
type
type1=class; // предварительное описание
type0 = class
a:type1;
end;
type1 = class
a:type0;
end;
← →
a-leksey (2002-12-20 09:50) [9]Тоже интересное решение....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.01.02;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.003 c