Macro mit interner Fkt

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Macro mit interner Fkt

Beitrag von Winni »

m.fuchs hat geschrieben:
Di 9. Feb 2021, 12:33
Winni hat geschrieben:
Di 9. Feb 2021, 11:15
Müssen denn 270 Klassen wirklich sein?
Durch die advanced Records kann man fast das Gleiche wie mit Klassen erreichen.
Es fehlt dann die Vererbung und damit hat man dann eventuell jede Menge Code-Duplikation.
Also eher ein Nachteil. Jetzt käme die Frage nach dem Vorteil.
Hi!

Also die Vererbung haben wir schon selbst gemacht, bevor die Records advanced waren:

Code: Alles auswählen

Type

  TRec1 = Record
                  a: ;integer;
                  b: string;
                  c: single:
                 procedure Flip:
                 Procedure Flop:
               end;

Trec2 = Record
              R1: Trec1;
              someThing : TSomething;
              end;
Und so weiter.

Vorteil1: Wenn irgendwo Mist passiert, bist Du selbst zuständig und musst Dich nicht erst mühsehlig in fremden Code einlesen, um dann dort den Fehler zu finden.Es werden doch täglich Bugs oder Schludrigkeiten in fpc/Lazarus-Units gefunden ==> internationales Forum.
Vorteil 2: Keine Pflicht für create und destroy mehr.
Vorteil 3: Keine Einschränkungen wie bei den Properties mehr .
Vorteil 4: Keine Notwendigkeit dür getter und setter bei properties mehr.
Vorteil 5: Kürzerer und lesbarerer Code.

Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von m.fuchs »

Winni hat geschrieben:
Di 9. Feb 2021, 18:37
Also die Vererbung haben wir schon selbst gemacht, bevor die Records advanced waren:
Das ist keine Vererbung sondern eine verkettete Liste mit unterschiedlichen Typen. Das hat nichts mit Vererbung zu tun und ersetzt diese keinesfalls.
Winni hat geschrieben:
Di 9. Feb 2021, 18:37
Vorteil1: Wenn irgendwo Mist passiert, bist Du selbst zuständig und musst Dich nicht erst mühsehlig in fremden Code einlesen, um dann dort den Fehler zu finden.Es werden doch täglich Bugs oder Schludrigkeiten in fpc/Lazarus-Units gefunden ==> internationales Forum.
Dieser "Vorteil" hat nichts mit OOP zu tun, sondern damit ob du Fremdbibliotheken nutzt oder nicht.
Winni hat geschrieben:
Di 9. Feb 2021, 18:37
Vorteil 2: Keine Pflicht für create und destroy mehr.
Dafür aber auch keine dynamischen Objekte mehr. Es sei denn du schießt wild mit Pointern auf deine Records. Aber das widerspricht dann deinem Vorteil 5.
Winni hat geschrieben:
Di 9. Feb 2021, 18:37
Vorteil 3: Keine Einschränkungen wie bei den Properties mehr .
Welche Einschränkungen sollen das sein?
Winni hat geschrieben:
Di 9. Feb 2021, 18:37
Vorteil 4: Keine Notwendigkeit dür getter und setter bei properties mehr.
Hast du bei OOP in Pascal nicht, du kannst Properties direkt auf Felder mappen.


Was soll daran lesbar sein, wenn man durch 100 Elemente durchiterieren muss um an bestimmte Felder zu gelangen?

Code: Alles auswählen

  MyRec.R5.R4.R3.R2.R1.a := 10;
Super lesbar. Wenn man sich Hosen mit Kneifzangen anzieht vielleicht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Schade das wir jetzt etwas vom eigentlichen Thema abkommen.

Es geht hier um Macros und nicht um OOP oder verschachtelte Records (was in meinen Augen schlechtes Codung ist. Stimme da m.fuchs zu: ich brauche das "Überschreiben von virtuellen methoden"! was in Records keinesfalls möglich ist).

Ich wäre da vielmehr dran interessiert wie das mit den Generics, als Äquivalent zu den Macros funktionieren soll.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von Socke »

hubblec4 hat geschrieben:
Di 9. Feb 2021, 20:48
Ich wäre da vielmehr dran interessiert wie das mit den Generics, als Äquivalent zu den Macros funktionieren soll.
Mein Problem hierbei ist, dass du im Generic auf den zu spezialisierenden Typen selbst referenzieren willst.
Daher funktioniert mein Ansatz hier leider nicht (Illegeal expression / Error in type definition):

Code: Alles auswählen

type
  TEbmlUInteger = class(TObject); // Basisklasse
  generic TGenericTEbmlUInteger<EBML_CLASS> = class(TEbmlUInteger)
  public
    constructor Create(const ElementToClone: EBML_CLASS); virtual; abstract;
  end;
  TEbmlVersion = specialize TGenericTEbmlUInteger<TEbmlVersion>;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Macro mit interner Fkt

Beitrag von Winni »

m.fuchs hat geschrieben:
Di 9. Feb 2021, 19:57


Was soll daran lesbar sein, wenn man durch 100 Elemente durchiterieren muss um an bestimmte Felder zu gelangen?

Code: Alles auswählen

  MyRec.R5.R4.R3.R2.R1.a := 10;
Super lesbar. Wenn man sich Hosen mit Kneifzangen anzieht vielleicht.

Code: Alles auswählen

Form1.Canvas.pen.color := clRed;
Gibt bestimmt noch tiefer verschachtelte properties in Lazarus.
Muss man sich bei der Vergabe der Namen etwas anstrengen.
Obiges war nur ein Beispiel! Gehirn einschalten!

Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von m.fuchs »

@Winni: Ich verwende jetzt mal deinen Diskussions"stil", vielleicht fällt dir dabei ja etwas auf.
Winni hat geschrieben:
Mi 10. Feb 2021, 10:51
m.fuchs hat geschrieben:
Di 9. Feb 2021, 19:57

Code: Alles auswählen

  MyRec.R5.R4.R3.R2.R1.a := 10;

Code: Alles auswählen

Form1.Canvas.pen.color := clRed;
Gibt bestimmt noch tiefer verschachtelte properties in Lazarus. Muss man sich bei der Vergabe der Namen etwas anstrengen.
Obiges war nur ein Beispiel! Gehirn einschalten!
Schalt mal dein Gehirn ein, schnapp dir ein Buch und lerne erst einmal was Objektorientierung ist, bevor du hier Stuss vom Stapel lässt.

Dein Beispiel mit Form.Canvas.Pen.Color ist keine Vererbung, sondern geschachtelte Objekte. Die würden als bei deiner sogenannten Idee von Vererbung noch dazu kommen.
Abgesehen davon habe ich dir geschrieben, dass das sowieso keine Vererbung ist, weil die wesentlichen Merkmale fehlen.
Also informiere dich gefälligst bevor du hier Unfug verbreitest. Vielleicht hast du dann auch keine Angst mehr vor OOP und musst nicht krampfhaft nach seltsamen Alternativen suchen.

Weitere Diskussionen dazu bitte in einem Extra-Thread.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Socke hat geschrieben:
Mi 10. Feb 2021, 10:11
hubblec4 hat geschrieben:
Di 9. Feb 2021, 20:48
Ich wäre da vielmehr dran interessiert wie das mit den Generics, als Äquivalent zu den Macros funktionieren soll.
Mein Problem hierbei ist, dass du im Generic auf den zu spezialisierenden Typen selbst referenzieren willst.
Daher funktioniert mein Ansatz hier leider nicht (Illegeal expression / Error in type definition):

Code: Alles auswählen

type
  TEbmlUInteger = class(TObject); // Basisklasse
  generic TGenericTEbmlUInteger<EBML_CLASS> = class(TEbmlUInteger)
  public
    constructor Create(const ElementToClone: EBML_CLASS); virtual; abstract;
  end;
  TEbmlVersion = specialize TGenericTEbmlUInteger<TEbmlVersion>;

Recht vielen Dank für diese Antwort.

So im groben verstehe ich das mit den Generics schon.
Man bastelt sich halt einen speziellen Typen eines Types(richtig?).

Code: Alles auswählen

TEbmlVersion = specialize TGenericTEbmlUInteger<TEbmlVersion>;
Was wenn ich nun weitere Methoden zu TEbmlVersion hinzufügen möchte, die nur dort sein dürfern
(und nicht in der TEbmlUInteger klasse)?


Dazu kommt noch das TEbmlElement die Basis klasse aller Elemente ist, und dann gibt es noch ein paar EBML-TypKlassen die von TEbmlElement abgeleitet werden(wie TEbmlUInteger) und dann kommt erst die eigentliche Element-Klasse.
Und manchmal "schalten" sich da noch weitere Klassen dazwischen.

Hier mal ein Link zur EbmlElement.h aus dem EBML Projekt: https://github.com/Matroska-Org/libebml ... lElement.h


Ich habe überlegt mein Laz_EBML projekt open source zu machen.
Da ich weit entfernt davon bin ein Profi zu sein, hätte es sicher Vorteile da andere Profis vielleicht mitarbeiten können.
Seit einigen Jahren beschäfftige ich mich mit Matroska und EBML und helfe nun bei der Spec-Entwicklung.

Da ich aber lieber in Lazarus programmiere wollte ich diese beiden projekte gerne übersetzen.
1:1 wäre sicher ganz nett, aber das muss nicht unbedingt sein. Es sind ja DLL Dateien die man damit erzeugen kann, allerdings müsste man das selbst tun, die DLLs werden nicht mehr bereit gestellt. Das einbinden des c++Codes in ein c++ Projekt reicht da aus.

Daher wollte ich alles als Package aufbereiten, so das dann auch andere leicht und einfach mit Matroska arbeiten können.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von Socke »

hubblec4 hat geschrieben:
Mi 10. Feb 2021, 20:17
Was wenn ich nun weitere Methoden zu TEbmlVersion hinzufügen möchte, die nur dort sein dürfern
(und nicht in der TEbmlUInteger klasse)?
Das ist hier die einfachste Frage. Du kannst die Spezialisierung als eigene Klasse, von der man auch ableiten kann, betrachten.

Code: Alles auswählen

TEbmlVersion = class(specialize TGenericTEbmlUInteger<TEbmlVersion>)
public
  procedure DoSomething;
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Ok, verstehe. einfach wie sonst auch die Ableitung in den Klammern steht die BasisKlasse.

Und dennoch müssten nun bei TEbmlVersion die Methoden gecodet werden (construtor, usw.)
Und damit hätte ich wieder sehr viel identischen Quellcode.

Genau aus dem Grund hatte ich mich für die Macros entschieden weil ich dann eben nur 3 Zeilen Code für einen Klassen-Kopf habe.

Man muss ja bedenken das die Methoden-Rümpfe auch noch gecodet werden müssen.
Mit den Macros sinds nur 4 oder 5 Zeilen für alle identischen Methoden-Rümpfe.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von Socke »

hubblec4 hat geschrieben:
Mi 10. Feb 2021, 20:48
Und dennoch müssten nun bei TEbmlVersion die Methoden gecodet werden (construtor, usw.)
Und damit hätte ich wieder sehr viel identischen Quellcode.
Du kannst natürlich auch die Methoden schon in der generischen Klasse implementieren. Hier kannst du natürliche nur auf das zugreifen, was diese generische Klasse an Methoden und Eigenschaften selbst mitbringt (bzw. von den Elternklassen erbt).

Ein wenig Kopfzerbrechen bereitet mir noch die Clone Methode. Du kannst über den Namen des Generics den Rückgabetypen (oder beim Constructor den Parametertypen) auf die jeweilige Spezialisierung einschränken. Das funktioniert aber nur dann gut, wenn du nicht von der Spezialisierung ableitets. Bei weiteren Ableitungen schlägt aber die ganz normale Typprüfung zu.

Code: Alles auswählen

program Project1;

{$mode objfpc}{$H+}

type
  TEbmlElement = class(TObject);
  generic TMyGeneric<SpecClassName> = class(TEbmlElement)
    procedure DoSomethingGeneric;
    function Clone: TMyGeneric;
  end;
  TEbmlVersion = specialize TMyGeneric<Integer>;   
  TEbmlStringElement = class(specialize TMyGeneric<String>)
  public
    procedure DoSomethingStringSpecific;
  end;

procedure TMyGeneric.DoSomethingGeneric;
var
  x: TMyGeneric;
begin
  x := Self;
  if Assigned(x) then
    x.DoSomethingGeneric;
end;

function TMyGeneric.Clone: TMyGeneric;
begin
  Result := Self;
end;

var
  Version: TEbmlVersion;
  StrElement: TEbmlStringElement;
  StrSpecialized: specialize TMyGeneric<String>;
begin
  Version := Version.Clone; // geht, da TEbmlVersion identisch zu specialize TMyGeneric<Integer> ist
  StrElement := StrElement.Clone;  // geht nicht, da TEbmlStringElement von specialize TMyGeneric<String> abgeleitet ist.
  StrSpecialized := StrSpecialized.Clone;  // geht, da alle Spezialisierungen mit den selben Identifiern zur selben Spezialisierung führen
end.
Selbstverständlich kann man das mit einem Typecast trotzdem zuweisen, aber das war nicht der Sinn der Generics.
Lösen lässt sich das durch einen überladenen Zuweisungsoperator:

Code: Alles auswählen

operator :=(src: specialize TMyGeneric<String>): TEbmlStringElement;
begin
  Result := TEbmlStringElement(src);
end;
var
  StrElement: TEbmlStringElement;
begin
  StrElement := StrElement.Clone;  // geht jetzt, da der überladene Zuweisungsoperator verwendet wird
end.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Mhh....
Ich weis nicht, das sieht ein wenig verwirrend für mich aus.

Das mag aber auch sicher daran liegen das du jetzt eben nicht mal auf die schnelle EBML verstehst, ich habe dazu fast ein halbes Jahr den c++ Code studiert.

Code: Alles auswählen

TEbmlVersion = specialize TMyGeneric<Integer>;
// das ist so nicht richtig TEbmlVersion basiert auf dem Type TEbmlUInteger und nicht Integer

TEbmlElement = class;
TEbmlUInteger = class(TEbmlElement); -> es gibt noch weitere EBML Type-Klassen z.B. TEbmlSInteger oder TEbmlMaster
TEbmlVersion = class(TEbmlUInteger);


// wegen der Clone Methode:
// ja die gibts auch, und eben das Clonen mittels constructor
// das TEbmlMaster Element zum beispiel ist kein Daten element sondern enthält eine Liste von TEbmlElementen und weitere besondere Master-Eigenschaften
// daher gibt es in dem constructor eine Kopier-Routine für die EbmlElement-Liste

Die Ableitung der Klassen ist sehr einfach so wie bei bekannten Laz Klassen oder Komponenten.
Zum beispiel bei einer Combobox, da werden auch von TObject bis zur TCombobox viele Zwichenklassen verwendet. Dort kommt ja auch kein generic Type vor.

So ähnlich ist es bei EBML ja auch. Die "End"-Klasse steuert lediglich beim ertsellen was für ein EBML-Type verwendet wird und ein paar andere wichtige Einstellungen, daher denke ich ist die Generic sache nicht wirklich notwendig.

Denn auch dort muss man ja die Metheode DoSomething anlegen und es gäbe ja noch weitere.
Aber das jetzt alles hier zu erklären wäre zu viel.

Generic steht doch eher für allgemein/typisch aber die Ebml Typen und Ebml Elemente sind alle sehr spezifisch. Das einzige was gemeinsam ist sind die Methoden und da auch nur die Methoden Namen und deren Bedeutung, aber ein TEbmlUInteger.ReadData() macht was völlig anderes als TEbmlMaster.ReadData().

Hier nochmal ein Hinweis für Winni:
Durch die OOP kann ich jetzt beim Code schreiben immer die BasisKlasse TEbmlElement verwenden
und kann da TEbmlElement.ReadData() nutzen.
Ich muss mir also im Vorfeld keine Gedanken darüber machen ob das Element ein Master ist oder ein UInteger. Das tolle ist, das die Methode ReadData() "überschrieben" wird und beim Ausführen der TEbmlElement.ReadData() die Read-Methode vom Master Element genutzt wird(wenn das Element zur Laufzeit ein Master ist)

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von Socke »

hubblec4 hat geschrieben:
Do 11. Feb 2021, 00:04
Das mag aber auch sicher daran liegen das du jetzt eben nicht mal auf die schnelle EBML verstehst, ich habe dazu fast ein halbes Jahr den c++ Code studiert.
Deine Beispiele sind aber auch sehr vage gehalten. Insbesondere fehlen mir bisher die Informationen zu den Unterschieden zwischen den verschiedenen Klassen. Daher demonstrieren meine Beispiele auch nur die Syntax. Die Übertragung in deinen Anwendungsfall ist dann deine Aufgbe.
hubblec4 hat geschrieben:
Do 11. Feb 2021, 00:04
Generic steht doch eher für allgemein/typisch aber die Ebml Typen und Ebml Elemente sind alle sehr spezifisch. Das einzige was gemeinsam ist sind die Methoden und da auch nur die Methoden Namen und deren Bedeutung, aber ein TEbmlUInteger.ReadData() macht was völlig anderes als TEbmlMaster.ReadData().
Wenn du OOP verwendest, kannst du die Methoden doch mit oder ohne Generics überschreiben. Welchen Vorteil bieten dir hier Macros an, wenn die Implementierung ohnehin spezifisch ist?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Socke hat geschrieben:
Do 11. Feb 2021, 09:58
hubblec4 hat geschrieben:
Do 11. Feb 2021, 00:04
Das mag aber auch sicher daran liegen das du jetzt eben nicht mal auf die schnelle EBML verstehst, ich habe dazu fast ein halbes Jahr den c++ Code studiert.
Deine Beispiele sind aber auch sehr vage gehalten. Insbesondere fehlen mir bisher die Informationen zu den Unterschieden zwischen den verschiedenen Klassen. Daher demonstrieren meine Beispiele auch nur die Syntax. Die Übertragung in deinen Anwendungsfall ist dann deine Aufgbe.
Ja da hast du recht, aber ich wollte in dem Chat jetzt nicht das Thema wechseln.
Und EBML lässt sich auch nicht einfach mal so in 2 Beiträgen erklären.
Ich hatte ja einen Link gepostet der zum c++ Projekt führt, dort kann man auch nachlesen wie das mit den Macros gemacht ist, und was damit bezweckt wird.
Socke hat geschrieben:
Do 11. Feb 2021, 09:58
hubblec4 hat geschrieben:
Do 11. Feb 2021, 00:04
Generic steht doch eher für allgemein/typisch aber die Ebml Typen und Ebml Elemente sind alle sehr spezifisch. Das einzige was gemeinsam ist sind die Methoden und da auch nur die Methoden Namen und deren Bedeutung, aber ein TEbmlUInteger.ReadData() macht was völlig anderes als TEbmlMaster.ReadData().
Wenn du OOP verwendest, kannst du die Methoden doch mit oder ohne Generics überschreiben. Welchen Vorteil bieten dir hier Macros an, wenn die Implementierung ohnehin spezifisch ist?
Vielleicht kurz zur Erklärung als Beispiel mal an Tieren:
Es gibt soweit ich weis über 100.000Tier Arten und über 10 Trillionen Tiere auf der Welt.
Die Basis Klasse ist also TTier.
Dann würden wir ein paar TierTyp-Klassen von TTier ableiten, sagen wir mal TFleischfresser und TPfanzenfresser. (aber wir könnten und sollten da noch weitere Typen anlegen)
Nun wirds dann etwas konkreter, denn für jedes Tier legen wir nun eine Klasse an.
Damit haben wir dann 10 Trillionen Klassen.

Und in all diesen Klassen haben wir nun immer wieder die gleichen Methoden-Namen stehen. Weil diese Methoden die Basis Methoden überschreiben.

Code: Alles auswählen

TTier = class
private
FID: QWord; // die eineindeutige ID
FLebt: Boolean;

protected:
procedure Tier_Isst_gerade(const Beute: TBeute); virtual;
procedure Tier_schlaeft(const dauer: Integer); virtual;
procedure Tier_Populiert; virtual;

end;

TFleischfresser = class(TTier)


end;

TPflanzenfresser = class(TTier)


end;


TMeinHund = class(TFleischfresser)

procedure Tier_isst_gerade(const Beute: TBeute); override;
procedure Tier_schlaeft(const Dauer: Integer); override;
procedure Tier_Populiert; override;

end;


TMeineKatze = class(TFleischfresser)

procedure Tier_isst_gerade(const Beute: TBeute); override;
procedure Tier_schlaeft(const Dauer: Integer); override;
procedure Tier_Populiert; override;

end;

TMeinWolf = class(TFleischfresser)

procedure Tier_isst_gerade(const Beute: TBeute); override;
procedure Tier_schlaeft(const Dauer: Integer); override;
procedure Tier_Populiert; override;

end;

TMeinHase = class(TPflanzenfresser)

procedure Tier_isst_gerade(const Beute: TBeute); override;
procedure Tier_schlaeft(const Dauer: Integer); override;
procedure Tier_Populiert; override;

end;

TNachbarsHase = class(TPflanzenfresser)

procedure Tier_isst_gerade(const Beute: TBeute); override;
procedure Tier_schlaeft(const Dauer: Integer); override;
procedure Tier_Populiert; override;

end;



// Wie du siehst stehen in allen End-Klassen die gleichen  Methoden (Namen)
// und genau da kommt der Macro ins spiel

{define CLASS_HEAD :=
             procedure Tier_isst_gerade(const Beute: TBeute); override;
	     procedure Tier_schlaeft(const Dauer: Integer); override; 
	     procedure Tier_Populiert; override;
}



// Nun kann man das alles kürzer schreiben

TMeinHund = class(TFleischfresser)

CLASS_HEAD

end;

Die Macros haben nichts mit Programmier-Logik zu tun, so wie es der ausgangs Titel dieses Themas sagt.
Die Macros werden nur dazu genutzt um Quellcode der identisch ist, diesen zu "ersetzen".

Die Macros sollen mir lediglich den Code verkürzen aber nicht Code-Logic beinhalten.

Die Methode Tier_Populiert wäre dann für eine Katze völlig was anders als die für ein Seepferdchen, aber dennoch ist der Methoden Name der gleiche.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Macro mit interner Fkt

Beitrag von m.fuchs »

Hm, dein Beispiel gefällt mir nicht so recht. Warum gibt es die Klassen TMeinHase und TNachbarsHase? Sollten beide Tiere nicht Instanzen der Klasse THase sein, statt eigene Klassen? Falls deine Implementation von EBML nach dem gleichen Denkmuster aufgebaut ist, dann läufst du meines Erachtens in die falsche Richtung.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: Macro mit interner Fkt

Beitrag von hubblec4 »

Also EBML ist eigentlich nur das Grundgerüst für die Binäre Speichermetohde, es ist von XML abgeleitet.
Und erst Matroska nutzt nun dieses System und setz oben drauf seine Elemente.

WebM (was eigentlich nur ein Matroska-Ableger ist) nutzt auch EBML.
Und bei Matroska gibt es zum Beispiel ein
"Language" Element, das findet man in dem Master Element TrackEntry.
Desweitern gibt es bei den Kapiteln ebenfalls ein ChapLangauge Element, beide sind mehr oder wenig identisch, was die Daten angeht.
ABER beide Elemente haben eine eindeutige ID und sie können eben nur innerhalb ihres vorgesehenen Master Element vorkommen, das verlangt die Matroska Syntax so.

Klar, mir ist da auch schon der Gedanke gekommen, warum man das so gemacht hat. und nicht nur ein Language Element verwendet und dieses dann in den jeweiligen Master Elementen verwendet.
Aber das hat alles sein sinn so. Aber dazu müsste man das alles vertiefen und sich reinfuchsen.

Aufjedenfall sind diese Klassen und dessen Vererbung nicht auf meinen Mist gewachsen, ich habe das lediglich 1:1 aus dem c++ Code übernommen, und ich gehe stark von aus das die Profis dort wissen was sie tun.

Steve Lohmme hat Matroska gegründet, der auch den VLC Player mit codet.
Daher vertraue ich mal der ganzen Struktur von EBML und Matroska.


Als ich noch keine so richtige Ahnung von OOP hatte, habe ich auch alles in Records gepackt und alles recht simple gehalten. Nur die IDs der Elemente waren vordefiniert.
Hatte den Vorteil das der parser recht fix ist, aber umständlicher Quellcode. Musste da für jeden Master eine eigene Parser Methoden schreiben.

Mit der jetzigen Struktur ist alles übersichtlich und der Code ist sehr kurz.

Antworten