class procedure instance_proc; static; inline;
procedure DoWork;
end;
TMyClass2 = class(TMyClass1)
class procedure instance_proc; static; inline;
end;
class procedure TMyClass2.instance_proc;
begin
WriteLn('TMyClass2.instance_proc');
end;
class procedure TMyClass1.instance_proc;
begin
WriteLn('TMyClass1.instance_proc');
end;
procedure TMyClass1.DoWork;
begin
WriteLn('TMyClass1.DoWork');
instance_proc;
end;
var
C: TMyClass2;
begin
C:=TMyClass2.Create;
C.DoWork; // write >> TMyClass1.DoWork
// TMyClass1.instance_proc
ReadLn;
end.
Но только, чтобы вывод вместо TMyClass1.instance_proc вызывался метод TMyClass2.instance_proc
Есть какой-то общепринятый способ решения такого?
(Я уже решил, позже покажу решение, но пока хочу собрать мнения)
конкретно в этом примере мне нужно чтобы метод instance_proc - был индивидуальным для каждого класса, а do_work - общим
В общем вот как сделал: program Project1; {$mode objfpc} {$modeswitch advancedrecords} {$iochecks off} type TInstanceMethodsBase = record class procedure proc; static; inline; end; TInstanceMethods1 = record class procedure proc; static; inline; end; TInstanceMethods2 = record class procedure proc; static; inline; end; generic TBaseClass<T> = class InstanceMethods: T; procedure test; inline; procedure own_method; virtual; end; generic TSubClass1<T> = class(specialize TBaseClass<T>) procedure own_method; override; end; generic TSubClass2<T> = class(specialize TBaseClass<T>) procedure own_method; override; end; procedure print(s: string); begin WriteLn(s); end; procedure TSubClass2.own_method; begin print(' +-> TSubClass2.own_method'); end; procedure TSubClass1.own_method; begin print(' +-> TSubClass1.own_method'); end; procedure TBaseClass.own_method; begin print(' +-> TBaseClass.own_method'); end; class procedure TInstanceMethodsBase.proc; begin print(' +-> TInstanceMethodsBase.proc'); end; class procedure TInstanceMethods1.proc; begin print(' +-> TInstanceMethods1.proc'); end; class procedure TInstanceMethods2.proc; begin print(' +-> TInstanceMethods2.proc'); end; procedure TBaseClass.test; begin print('TBaseClass.test'); InstanceMethods.proc; own_method; end; begin specialize TBaseClass<TInstanceMethodsBase>.Create.test; WriteLn; specialize TSubClass1<TInstanceMethods1>.Create.test; WriteLn; specialize TSubClass2<TInstanceMethods2>.Create.test; // наборами методов теперт можно жонглировать как захочется и прикрепить их к любому классу // абсолютно бесплатно с т.з. InstanceSize и CPU-overhead ReadLn; end. Вывод TBaseClass.test +-> TInstanceMethodsBase.proc +-> TBaseClass.own_method TBaseClass.test +-> TInstanceMethods1.proc +-> TSubClass1.own_method TBaseClass.test +-> TInstanceMethods2.proc +-> TSubClass2.own_method
Имхо хрен какая-то. Но может я чего-то не понимаю. По сути ты также засовываешь в инстанс рекорд со статическим методом, чем это отличается от просто процедурного филда - непонятно. Единственно экономишь на инициализации этого поля
набросайте код - я скажу в чем разница
Набросал сам - можете посравнивать сами program Project1; {$mode delphi} {$modeswitch advancedrecords} {$iochecks off} type TRec = record class procedure method; static; inline; end; TMyClass<T> = class R: T; procedure proc; end; procedure TMyClass<T>.proc; begin R.method; end; class procedure TRec.method; begin WriteLn('kek'); end; var C: TMyClass<TRec>; begin C:=TMyClass<TRec>.Create; C.proc; ReadLn; end. program Project1; {$mode delphi} type TMyClass = class method: procedure (); procedure proc; end; procedure TMyClass.proc; begin method; end; procedure method; begin WriteLn('kek'); end; var C: TMyClass; begin C:=TMyClass.Create; C.method:=method; C.proc; ReadLn; end.
Обсуждают сегодня