169 похожих чатов

Итак... понадобилось мне примерно следующее: program Project1; type TMyClass1 = class

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
Есть какой-то общепринятый способ решения такого?
(Я уже решил, позже покажу решение, но пока хочу собрать мнения)

5 ответов

16 просмотров
notme- Автор вопроса

конкретно в этом примере мне нужно чтобы метод instance_proc - был индивидуальным для каждого класса, а do_work - общим

notme- Автор вопроса

В общем вот как сделал: 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

notme
В общем вот как сделал: program Project1; {$mode o...

Имхо хрен какая-то. Но может я чего-то не понимаю. По сути ты также засовываешь в инстанс рекорд со статическим методом, чем это отличается от просто процедурного филда - непонятно. Единственно экономишь на инициализации этого поля

notme- Автор вопроса
notme- Автор вопроса
notme
набросайте код - я скажу в чем разница

Набросал сам - можете посравнивать сами 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.

Похожие вопросы

Обсуждают сегодня

Какой-то там пердун в 90-х решил, что есть какая-то разная типизация. Кого вообще это волнует?
КТ315
49
void terminal_scroll() { memmove(terminal_buffer, terminal_buffer + VGA_WIDTH, buffer_size - VGA_WIDTH); memset(terminal_buffer + buffer_size - VGA_WIDTH, 0, VGA_WIDTH); ...
Егор
47
Всем привет! Подскажите, пожалуйста, в чем ошибка? Настраиваю подключение к MySQL. Либы лежат рядом с exe. Все как по "учебнику"
Евгений
16
А можете как-то проверить меня по знаниям по ассемблеру?
A A
132
Здравствуйте! У меня появилась возможность купить книгу "Изучай Haskell во имя добра!". Но я где-то слышал, что эта книга устарела. Насколько это правда??
E
22
Здравствуйте! Я вот на stepic решаю задачи на хаскеле https://stepik.org/lesson/8443/step/8?unit=1578 мой код import Data.List (isInfixOf) removing :: String -> [String] ->...
E
10
Камрады, кто тесно работал с vtv, хотел уточнить. Ширина column задаётся жёстко на этапе создания дерева или можно в рантайме ее менять программно (не мышкой)?
Ed Doc
10
да ладно ... что там неочевидного ? глянуть в исх-ки датасета и/или кверика чтобы понять в каком месте и как выполняется обращения к св-вам blablaSQL - минутное дело, даже е...
Сергей
7
Здесь для arm кто-нибудь кодит ?
Nothing
52
Всем привет, у меня есть сервер принимающий входящие HTTP подключения, как проверить, что подключение было через прокси или нет, есть какие то поля в заголовках по которым мо...
DS
8
Карта сайта