Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kind as Opa innerhalb der Deklerartion (https://www.delphipraxis.net/139971-kind-opa-innerhalb-der-deklerartion.html)

dmdjt 9. Sep 2009 12:26


Kind as Opa innerhalb der Deklerartion
 
Gibt es eine Möglichkeit eine Methode von Großvater bis Kind zu vererben... allerdings beim Kind die Methode vom Großvater direkt aufzurufen?

Hört sich vielleicht etwas konfus an, also hier der Code wie ich es gerne hätte:

Delphi-Quellcode:
procedure TOpa.tuwas;
begin
  showmessage('Opa');
end;


procedure TVater.tuwas;
begin
  showmessage('Vater');
end;

procedure TKind.tuwas;
begin
 (self as TOpa).tuwas;
end;
Also bei mir kommt dann ein StackOverflow. Das würde ich gerne besser verstehen. Erwartet hätte ich vielleicht eine Zugriffsverletzung oder was anderes... aber StackOverflow verweundert mich schon ein wenig.

ChrisE 9. Sep 2009 12:58

Re: Kind as Opa innerhalb der Deklerartion
 
Hallo,

sag mal wie die Klassenherachie aufgebaut ist?
Wie ist tuwas Deklariert (in der abstrakten Basis-Klasse)?

Namenloser 9. Sep 2009 13:06

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von dmdjt
Also bei mir kommt dann ein StackOverflow. Das würde ich gerne besser verstehen. Erwartet hätte ich vielleicht eine Zugriffsverletzung oder was anderes... aber StackOverflow verweundert mich schon ein wenig.

Das macht schon Sinn, wenn du die Prozedur TuWas in der Basisklasse als virtual, und inder abgeleiteten als override deklariert hast. Override bewirkt, dass alle Aufrufe dieser Funktion, sowohl aus der abgeleiteten Klasse, als auch aus der Basisklasse auf die neue Version umgeleitet werden. Die Funktion ruft sich also imemr wieder selbst auf, bis der Stack voll ist.

Eine Möglichkeit die Funktion des Opas aufzurufen kenne ich nicht. Wenn es nur um den Vater ginge, ginge es mit inherited.

dmdjt 9. Sep 2009 13:17

Re: Kind as Opa innerhalb der Deklerartion
 
Der sohn ist vom Vater und der Vater vom Opa abgeleitet. Das ganze soll nur ein Beispiel sein und die Methode TuWas gibt nur eine MessageBox mit entweder dem Text 'Opa' (TOpa) oder 'Vater' (TVater) aus. Bei TKind sollte allerdings wieder 'Opa' ausgegeben werden.

procedure Tuwas; ist public deklariert

Mit virtual, abstract usw. (wie heißen diese Schlüsselworte eigentlich?) kenn ich mich nicht mehr besonders gut aus und hab einfach nur herum probiert. Liegt es vielleicht an denen?

Anwendungsbeispiele fallen mir momentan keine ein. Ich habe die Frage nur irgendwo einmal gelesen und dachte, dass man das vielleicht so implementieren könnte. Ich versuche mir OOP nach längerer Abstinz wieder besser ins Gehirn zu hämmern. Was gar nicht so leicht ist, weil mein bisheriges Wissen ein zur Hälfte vergessenes Halbwissen ist.



Der Fehler tritt auch ohne override auf. Egal als was ich die Methode deklariere.

Edit: Wo bleiben meine Marnieren... Herzlichen Dank natürlich!!

Neutral General 9. Sep 2009 13:26

Re: Kind as Opa innerhalb der Deklerartion
 
Hi,

Ich weiß nicht ob das geht.. entspricht evtl auch nicht dem Grundgedanken von OOP. Aber du könntest versuchen:

Delphi-Quellcode:
procedure TKind.tuwas;
begin
 inherited (inherited tuwas);
end;
weiß allerdings nicht ob man inherited doppelt verwenden kann....

Tryer 9. Sep 2009 13:31

Re: Kind as Opa innerhalb der Deklerartion
 
Auch bei TOpa(Kind).tuwas wird immer die überschiebene Methode aufgerufen, welche sich auf diesem Wege selber aufruft -> StackOverflow.
Mit "inherited" kommt man nur bis zu TVater zurück. Da bestände dann die Möglichkeit für "Sauereien" ala
Delphi-Quellcode:
if (Self is TKind) then
  inherited
else
  ShowMessage('Vater');
Damit ruft ein inherited-Aufruf vom Kind über den Vater - Umweg die Opa-Methode auf. Nicht zu empfehlen da unübersichtlich und unflexibel.

Die Möglichkeit das ganze zu umgehen wäre das verdecken der virtuellen Methode von TOpa (-> reintroduce;). Dadurch existieren die Methoden dann "nebeneinander" und der Aufruf gelingt.

MfG,
Dirk

Meflin 9. Sep 2009 13:32

Re: Kind as Opa innerhalb der Deklerartion
 
Im Zweifelsfall musst du eben ein Parent-Feld einführen (und beim Create richtig belegen).

Sowas wie self.parent.parent.TuWas sollte auf jeden Fall gehen :stupid:

dmdjt 9. Sep 2009 13:43

Re: Kind as Opa innerhalb der Deklerartion
 
Delphi-Quellcode:
procedure TKind.tuwas;
begin
inherited (inherited tuwas);
end;
Geht leider nicht...zumindest nicht in der Form: Missing Operator or semicolon.

Ihr habts einen Haufen interessanter Ideen!

Vielen Dank an euch alle!

Tryer 9. Sep 2009 13:47

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von Meflin
Sowas wie self.parent.parent.TuWas sollte auf jeden Fall gehen :stupid:

Wobei das dann nur funktioniert wenn auch eine Instanz von TOpa existiert. Ich denke mal hier geht es eher ums Klassendesign. Die Bezeichnungen Kind/Vater/Opa sind nur etwas ungünstig gewählt.

Der richtige Weg wäre wohl eher eine Methode nicht so zu überschreiben das sie in der nachfolgenden Klasse nicht zu gebrauchen ist, oder noch besser auch TKind von TOpa abzuleiten.

MfG,
Dirk

ChrisE 9. Sep 2009 13:52

Re: Kind as Opa innerhalb der Deklerartion
 
Ich musste es mir auch erst wieder klar machen, aber es ist wie alle es sagen :mrgreen:

StackOverflow ist klar weil:

Wenn du eine Klasse erstellst, werden ja alle Speicherbereich erstellt die so benötigt werden und eben auch die Ein-Sprungpunkte der Methoden der Klasse. Das Ermöglicht ja das LateBinding / SpäteBindung. D.h. erstmal das ja zum Zeitpunkt das Programmschreibens noch nicht klar ist, welche Methoden tatsächlich aufgerufen werden.
Delphi-Quellcode:
var Person: TPerson;
//...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Person.Tuwas;
end;
wird jetzt in Button2click ein Kind erstellt mit
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Person := TKind.Create;
end;
muss ja irgend etwas dafür sorgen, dass bei Button1Click die richtige Methode aufgerufen wird. Wenn du also den Contructor von TKind aufrufst, wird eine Klasse erstellt die Identisch zu TPerson ist und als Einsprungpunkt für TuWas immer die Methode von TKind.Tuwas hat.

Dieser Mechanismus erzeugt jetzt den Stackoverflow, denn egal welchen Typcast du auf Person außerhalb der Klassen anwendest - es wird immer TKind.Tuwas aufgerufen aufgrund des Einsprungpunktes. Das selbe gilt natürlich für innerhalb der Klassen.

Somit kommt es in dein ursprünglicher Aufruf von (Self as TOpa).Tuwas zum Stackoverflow. Es ergibt sich eine Rekursion unendlicher Tiefe und der Stack läuft über wegen der Rücksprungadressen etc.

Ich hoffe das hilft dir etwas beim Verständnis.

Gruß, Chris

[EDIT] 2x Button1Click :pale: [/EDIT]

dmdjt 9. Sep 2009 14:03

Re: Kind as Opa innerhalb der Deklerartion
 
Oja, das hilft!

Und damit hat die Frage sich wirklich ausgezahlt. Auch wenn sie in ihrer Ursprungsform irgendwie nicht so besonders sinnvoll erscheint. (Normal hätte ich einfach bei TVater eine weitere Methode eingeführt und nicht jene von TOpa überschrieben.)

Manche Dinge versteht man erst richtig, wenn man ihre Grenzen findet.

Achja, warum sind die Bezichnungen Opa, Vater und Kind ungünstig gewählt? Dachte nur, dass so der Stammbaum schnell ersichtlich ist. Bin aber was Namensgebung betrifft irgendwie sehr schleißig sollte ich ändern :wink:

Aphton 9. Sep 2009 14:09

Re: Kind as Opa innerhalb der Deklerartion
 
Delphi-Quellcode:
  TOpa = class
  public
    procedure MeinName(); virtual;
  end;

  TVater = class( TOpa )
  public
    procedure MeinName(); override;
  end;

  TKind = class( TVater )
  public
    procedure MeinName(); override;
  end;

...
procedure TForm1.FormCreate(Sender: TObject);
var
  k: TKind;
begin
  k := TKind.Create;
  k.MeinName;
  k.Free;
end;

{ TOpa }
procedure TOpa.MeinName;
begin
  ShowMessage( 'Ich bin dein Opa' );
end;

{ TVater }
procedure TVater.MeinName;
begin
  inherited;
  ShowMessage( 'Ich bin dein Vater, krchh (:D)' );
end;

{ TKind }
procedure TKind.MeinName;
begin
//  inherited;
  asm
    call TOpa.MeinName
  end;
  ShowMessage( '(Kind:) a gugugugu' );
end;

dmdjt 9. Sep 2009 14:17

Re: Kind as Opa innerhalb der Deklerartion
 
Hey, das ist cool und funktioniert!

Wie bist Du auf die Idee gekommen und noch viel wichtiger: Warum geht das mit Inline-Assembler?

Edit:
Okay, ich kanns mir vorstellen warum. Angelegt wird die Methode ja irgendwo. Und mit call springt man halt zu eben jener.

Aphton 9. Sep 2009 14:19

Re: Kind as Opa innerhalb der Deklerartion
 
Wie bin ich auf die Idee gekommen?
Hab einfach das Projekt debuggt, und gesehen, wie ein inherited Aufruf in Assembler aussieht.

Warum funktioniert das?
:firejump:

MfG

sirius 9. Sep 2009 14:23

Re: Kind as Opa innerhalb der Deklerartion
 
@Aphton
Das funktioniert nicht!
Greif mal in TOpa.MeinName auf self zu (Also lass dir irgendein sinnvolles Feld einfallen)!

Ansonsten kannst du auch MeinName als Klassenmethode deklarieren, dann geht es auch ohne ASM.
Edit: Aber eine Klassenmethode ist ja nicht das Ziel.

Edit2: Folgende Änderung:
Delphi-Quellcode:
 TOpa = class
  private
     x:Integer;
  public
    procedure MeinName(); virtual;
  end;

//und:

procedure TOpa.MeinName;
begin
  x:=5;
  ShowMessage( 'Ich bin dein Opa' );
end;

procedure TKind.MeinName;
var i:Integer;
begin
  for i:=0 to 0 do showmessage('Damit es nicht durch Zufall doch klappt');
  asm
    call TOpa.MeinName
  end;
  ShowMessage( '(Kind:) a gugugugu' );
end;

Namenloser 9. Sep 2009 14:23

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von dmdjt
Hey, das ist cool und funktioniert!

Wie bist Du auf die Idee gekommen und noch viel wichtiger: Warum geht das mit Inline-Assembler?

Die Frage ist eher: Geht das auch ohne? Also nur TOpa.MeinName()?

sirius 9. Sep 2009 14:29

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von dmdjt
Mit virtual, abstract usw. (wie heißen diese Schlüsselworte eigentlich?) kenn ich mich nicht mehr besonders gut aus und hab einfach nur herum probiert. Liegt es vielleicht an denen?

Ja.

Aphton 9. Sep 2009 14:29

Re: Kind as Opa innerhalb der Deklerartion
 
Nö, das tut es nicht.
Ich nehme mal an, per Inline Asm ruft man da direkt im Proc-Chain die Methode(Proc/Func) auf,
da ja bei der Vererbung den erbenden Klassen alle Methoden der Parentklasse zur Verfügung stehen.

Aber ich rate nur blöd rum... Deshalb halte ich mich an mein Avater :D

MfG

sirius 9. Sep 2009 14:31

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von NamenLozer
Die Frage ist eher: Geht das auch ohne? Also nur TOpa.MeinName()?

Wie gesagt: Es geht (eigentlich) nicht mal mit. Hier ist es nur Zufall, da self nicht benötigt wird.
Und bei einer Klassenmethode gänge es auch ohne, ja. Aber hier ging es ja um virtuelle Methoden.

Namenloser 9. Sep 2009 14:36

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von sirius
Zitat:

Zitat von NamenLozer
Die Frage ist eher: Geht das auch ohne? Also nur TOpa.MeinName()?

Wie gesagt: Es geht (eigentlich) nicht mal mit. Hier ist es nur Zufall, da self nicht benötigt wird.
Und bei einer Klassenmethode gänge es auch ohne, ja. Aber hier ging es ja um virtuelle Methoden.

Dass es mit einer Klassenmethode geht, ist klar. Was mir jedoch nicht gnaz klar ist, ist wieso der Zurgiff auf self nicht funktioniert: Wenn ich mich nicht irre steht self doch immer im Register EBX, und EBX wurde doch nicht verändert, müsste doch also in TOpa.MeinName immer noch auf das gleiche Objekt verweisen. Löscht call automatisch die Register, oder wie? :gruebel:

dmdjt 9. Sep 2009 14:40

Re: Kind as Opa innerhalb der Deklerartion
 
Habs getestet mit

Delphi-Quellcode:
TOpa = class
public
  alter : integer;
  procedure tuwas;
end;


procedure TOpa.tuwas;
begin
  showmessage('Großvater '+inttostr(self.alter));
end;
Opa, Vater und Kind haben ein Unterschiedliches Alter. Wenn Alter eine Konstante ist geht es. Wenn nicht, dann ist Alter = 0. Das ist mir klar. Und natürlich die Limitation an dem ganzen. Wird ja nirgendwo zugewiesen. Und wenn dann würde es auch nix bringen, weil man ja auf die KLasse und nicht auf das Objekt zugreift. Hab ich das richtig verstanden?

PS: Bin mal für einige Zeit weg...

sirius 9. Sep 2009 14:44

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von NamenLozer
Löscht call automatisch die Register, oder wie? :gruebel:

Nein, aber vor dem Call kann ja noch etwas stehen. Wenn nicht, dann passiert auch nix. Aber schon allein das Nutzen von dynamischen (Interface, String, dyn. Array) Variablen verändert ne Menge Register bevor deine Methode richtig anfängt.
Edit: Ein mov eax,self dürfte allerindg schon reichen. Das sind aber reichlich Verrenkungen.

Hawkeye219 9. Sep 2009 14:45

Re: Kind as Opa innerhalb der Deklerartion
 
Hallo,

abgesehen von möglichen Designfehlern in der Klassenhierarchie - wäre es nicht am einfachsten, dem fleißigen Opa eine weitere, nicht-virtuelle Methode zu spendieren?

Delphi-Quellcode:
type
  TOpa = class
    procedure TuWas; virtual;
    procedure OpaTutWas;
  end;

procedure TOpa.TuWas;
begin
  OpaTutWas;
end;

procedure TOpa.OpaTutWas;
begin
  // die eigentlichen Aktionen
end;

[...]

procedure TKind.TuWas;
begin
  OpaTutWas;
end;
Die neue Methode kann in allen abgeleiteten Klassen direkt aufgerufen werden.

Gruß Hawkeye

olee 9. Sep 2009 15:41

Re: Kind as Opa innerhalb der Deklerartion
 
Die Methode von Hawkeye219 funktioniert zwar,

aber wenn jetzt TOpa eine Klasse aus Delphi wie TMemo u.a. wäre, könnte man nicht
einfach die Source ändern :wink: .

Aber ich bin auch darauf gespannt, ob so was mit asm möglich ist.

ALso so inetwa wie das hier:

Delphi-Quellcode:
asm
  mov eax, self;
  call TOpa.MeinName;
end;

sirius 9. Sep 2009 15:44

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von olee
Aber ich bin auch darauf gespannt, ob so was mit asm möglich ist.

:gruebel: List hier eigentlich noch jemand ALLE bisherigen Kommentare?

Aphton 9. Sep 2009 15:45

Re: Kind as Opa innerhalb der Deklerartion
 
Delphi-Quellcode:
procedure TKind.MeinName;
var i:Integer;
begin
  asm
    pushad
  end;
  for i:=0 to 0 do showmessage('Damit es nicht durch Zufall doch klappt');
  asm
    popad
    call TOpa.MeinName
  end;
  ShowMessage( '(Kind:) a gugugugu' );
end;
:P

olee 9. Sep 2009 15:46

Re: Kind as Opa innerhalb der Deklerartion
 
Ich hab alles gelesen meine Frage war, ob durch dieses MOV danach auch die
Varaible self in TOpa.TuWas zu gebrauchen ist.

:?

Namenloser 9. Sep 2009 15:58

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von olee
Ich hab alles gelesen meine Frage war, ob durch dieses MOV danach auch die
Varaible self in TOpa.TuWas zu gebrauchen ist.

:?

Muss eigentlich. Allerdings steht self höchstwahrscheinlich nicht in EAX, denn EAX ist für den Funktionsrückgabewert reserviert.

sirius 9. Sep 2009 15:59

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von olee
Ich hab alles gelesen meine Frage war, ob durch dieses MOV danach auch die
Varaible self in TOpa.TuWas zu gebrauchen ist.

:?

Ja, ist es, siehe Beitrag #22
Edit: Sorry, den hatte ich editiert.... :pale:


@Aphton:
Delphi-Quellcode:
procedure TKind.MeinName;
var i:Integer;
    s:string;
begin
  asm
    pushad
  end;
  s:='test';
  for i:=0 to 0 do showmessage('Damit es nicht durch Zufall doch klappt');
  asm
    popad
    call TOpa.MeinName
  end;
  ShowMessage( '(Kind:) a gugugugu' +s);
end;
Aber mach doch, wie ich schon schrieb, ein mov eax,self direkt vor den Aufruf.

fajac 10. Sep 2009 08:38

Re: Kind as Opa innerhalb der Deklerartion
 
Etwas gekünstelt könnte man es so machen:

Delphi-Quellcode:
interface

type
  TOpa = class (TObject)
  public
    procedure SachWas (ARecurse : Integer = 0); virtual;
  end;

  TVater = class (TOpa)
  public
    procedure SachWas (ARecurse : Integer = 0); override;
  end;

  TSohn = class (TVater)
  public
    procedure SachWas (ARecurse : Integer = 0); override;
  end;

implementation

{ TOpa }

procedure TOpa.SachWas (ARecurse: Integer = 0);
begin
  ShowMessage ('Hallo Jungs!')
end;

{ TVater }

procedure TVater.SachWas (ARecurse: Integer = 0);
begin
  if ARecurse > 0 then
    inherited SachWas (ARecurse - 1)
  else
    ShowMessage ('Hallo Bub!')
end;

{ TSohn }

procedure TSohn.SachWas (ARecurse: Integer = 0);
begin
  if ARecurse > 0 then
    inherited SachWas (ARecurse - 1)
  else
    ShowMessage ('GuGu!')
end;

procedure AlleSagenWas(Sender: TObject);
var
  kind : TSohn;
begin
  kind := TSohn.Create;
  try
    kind.SachWas;
    kind.SachWas(1);
    kind.SachWas(2);
  finally
    kind.Free;
  end;
end;

uligerhardt 10. Sep 2009 09:02

Re: Kind as Opa innerhalb der Deklerartion
 
AUA. :wall:

Wenn man sowas braucht, dann stimmt ganz einfach die Klassenhierarchie nicht. Hier gilt halt nicht TSohn is a TVater is a TOpa. Da muss vermutlich irgendwo noch eine vierte Klasse rein, dann kann man sich die Verrenkungen sparen (asm :shock:).

sirius 10. Sep 2009 09:49

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von uligerhardt
Wenn man sowas braucht, dann stimmt ganz einfach die Klassenhierarchie nicht.

Sicher?

Ich habe das auch noch nie gebraucht, aber es ist in mehreren anderen Programmiersprachen möglich. Warum soll denn hier grad Delphi der Maßstab sein (außer, dass wir hier in einem Delphi-Forum sind)? Ich gebe zu, dass mir diesbezüglich theoretisches Wissen fehlt. Ich würde diesen Fakt (da er des öfteren in Delphi-Foren auftaucht) nur mal geklärt wissen. Nicht, dass das einer mal behauptet hat und alle anderen plappern das nur nach.

uligerhardt 10. Sep 2009 11:08

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von sirius
Zitat:

Zitat von uligerhardt
Wenn man sowas braucht, dann stimmt ganz einfach die Klassenhierarchie nicht.

Sicher?

Natürlich nicht, das ist nur ein Bauchgefühl. Allerdings ein ziemlich starkes. :mrgreen:

Zitat:

Zitat von sirius
Ich habe das auch noch nie gebraucht, aber es ist in mehreren anderen Programmiersprachen möglich. Warum soll denn hier grad Delphi der Maßstab sein (außer, dass wir hier in einem Delphi-Forum sind)?

Ich kenn das nur aus C++, wo man TOpa::MeineMethode schreiben kann. Das ist aber vermutlich eher aus Konsistenzgründen so gemacht, weil :: halt nunmal der Scope-Operator ist. Und benenn in C++ mal ne Basisklasse um - toll, wie oft man da AlterKlassenname::Methode durch NeuerKlassenname::Methode ersetzen darf. Deswegen sieht man ja auch oft
Code:
typedef Klassenname inherited; // oder base oder super oder ...
Zitat:

Zitat von sirius
Ich gebe zu, dass mir diesbezüglich theoretisches Wissen fehlt. Ich würde diesen Fakt (da er des öfteren in Delphi-Foren auftaucht) nur mal geklärt wissen. Nicht, dass das einer mal behauptet hat und alle anderen plappern das nur nach.

Ist mir klar, dass ich nicht der erste bin, der die Behauptung äußert. :-D

sirius 10. Sep 2009 12:03

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von uligerhardt
Ich kenn das nur aus C++, wo man TOpa::MeineMethode schreiben kann.

Und in Matlab schreibt man MeineMethode@TOpa, in Java schreibt man super.super ..... :wiejetzt:

uligerhardt 10. Sep 2009 12:24

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von sirius
Zitat:

Zitat von uligerhardt
Ich kenn das nur aus C++, wo man TOpa::MeineMethode schreiben kann.

Und in Matlab schreibt man MeineMethode@TOpa, in Java schreibt man super.super ..... :wiejetzt:

Wie "wie jetzt"? :P Ich kenn von Matlab nur den Namen und Java nur sehr oberflächlich.

Ist aber auch egal, ob's die Sprache freiwillig hergibt oder per Assembler - bevor ich sowas mache, überleg ich mir nochmal, ob meine Klassenhierarchie stimmt. So, meine 2 Cent. :-D

Blup 10. Sep 2009 13:03

Re: Kind as Opa innerhalb der Deklerartion
 
Wenns den unbedingt sein muss ...
Delphi-Quellcode:
type
  TOpa = class(TObject)
  private
    FAlter: Integer;
  public
    procedure SagWas; virtual;
    property Alter: Integer read FAlter write FAlter;
  end;

  TVater = class(TOpa)
  public
    procedure SagWas; override;
  end;

  TKind = class(TVater)
  public
    procedure SagWas; override;
  end;

  TSagWasProcedure = procedure (Self: Pointer);

procedure TOpa.SagWas;
begin
  showmessage(Format('Opa ist %d Jahre alt.', [Alter]));
end;

procedure TVater.SagWas;
begin
  showmessage(Format('Vater ist %d Jahre alt.', [Alter]));
end;

procedure TKind.SagWas;
var
  Proc: TSagWasProcedure;
begin
//  showmessage(Format('Kind ist %d Jahre alt.', [Alter]));
  Proc := @TOpa.SagWas;
  Proc(Self);
end;

procedure TFTest.Button6Click(Sender: TObject);
var
  K: TKind;
begin
  K := TKind.Create;
  K.Alter := 10;
  K.SagWas;
  K.Free;
end;
gehts auch ohne Assembler.

Aphton 10. Sep 2009 14:06

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von sirius
@Aphton:
Delphi-Quellcode:
procedure TKind.MeinName;
var i:Integer;
    s:string;
begin
  asm
    pushad
  end;
  s:='test';
  for i:=0 to 0 do showmessage('Damit es nicht durch Zufall doch klappt');
  asm
    popad
    call TOpa.MeinName
  end;
  ShowMessage( '(Kind:) a gugugugu' +s);
end;
Aber mach doch, wie ich schon schrieb, ein mov eax,self direkt vor den Aufruf.

Nö - was machst du, wenn die vorigen calls eax modifizieren?
Mit pusad "sichere" ich nur aus sicherheitsgründen die ganzen Register ... Man weiß ja nie, was zwischendrin so alles geschehen kann!

MfG

sirius 10. Sep 2009 14:13

Re: Kind as Opa innerhalb der Deklerartion
 
Zitat:

Zitat von Aphton
Mit pusad "sichere" ich nur aus sicherheitsgründen die ganzen Register ... Man weiß ja nie, was zwischendrin so alles geschehen kann!

Ich weiß, was du beabsichtigst. Aber wenn ich in der Funktion bspw. einen String habe, werden die Register bereits verändert bevor du auch nur etwas retten kannst (nähmlich in begin). Schau dir das Compilat an.
Aber, wie gesagt, es geht mit ASM und ohne ASM, aber nicht ohne Tricksen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz