[OOP] Include Datei mit Makros/Funktionen für OOP

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

[OOP] Include Datei mit Makros/Funktionen für OOP

Beitrag von helpy »

Hallo

Ich habe eine Include-Datei (Download: ClassTools.pbi) mit einigen Makros und Funktion geschrieben, womit ich z.B. folgendes machen kann:

Code: Alles auswählen

XIncludeFile "ClassTools.pbi"

;=======================================================
; Define the Class (Interface) of FIRST_CLASS
DEFINE_CLASS(FIRST_CLASS)
  SetName(Name.s)
  GetName.s()
  Release()
END_CLASS(FIRST_CLASS)


; Define Class data
DEFINE_CLASS_DATA(FIRST_CLASS)
  Name.s
END_CLASS_DATA

; Class Methods
METHOD_1(FIRST_CLASS,SetName,l,Name.s)
  CLASS_DATA\Name = Name
END_METHOD

METHOD_0(FIRST_CLASS,GetName,s)
  METHOD_RETURN(CLASS_DATA\Name)
END_METHOD

METHOD_0(FIRST_CLASS,Release,l)
  METHOD_RETURN(CLASS_RELEASE)
END_METHOD


; CLASS Constructor
CLASS_CONSTRUCTOR(FIRST_CLASS)
  VTABLE(FIRST_CLASS,SetName)
  VTABLE(FIRST_CLASS,GetName)
  VTABLE(FIRST_CLASS,Release)

  CONSTRUCTOR_INIT(FIRST_CLASS)
  CLASS_DATA\Name = "Initial Name"
END_CONSTRUCTOR(FIRST_CLASS)
;=======================================================

;Test FIRST_CLASS
Debug "--------------------------------"
Debug "Test of FIRST_CLASS"
Debug "--------------------------------"
oClass.IClass(FIRST_CLASS) = NEW_OBJECT(FIRST_CLASS)
Debug oClass\GetName()
oClass\SetName("New Name")
Debug oClass\GetName()
Debug oClass\Release()     ; returns #True if successful


;=======================================================
; Define the Class (Interface) of SECOND_CLASS
DEFINE_CLASS(SECOND_CLASS) Extends EXTEND_CLASS(FIRST_CLASS)  
                           ; need the Extends keyword becaus of a macro bug!
                           ; otherwise the Extends keyword would be in ClassTools.pbi
  SetCountry(Country.s)
  GetCountry.s()
END_CLASS(SECOND_CLASS)


; Define Class data
DEFINE_CLASS_DATA(SECOND_CLASS) Extends EXTEND_CLASS_DATA(FIRST_CLASS)
                                ; need the Extends keyword becaus of a macro bug!
                                ; otherwise the Extends keyword would be in ClassTools.pbi
  Country.s
END_CLASS_DATA

; Class Methods
METHOD_1(SECOND_CLASS,SetCountry,l,Country.s)
  CLASS_DATA\Country = Country
END_METHOD

METHOD_0(SECOND_CLASS,GetCountry,s)
  METHOD_RETURN(CLASS_DATA\Country)
END_METHOD

METHOD_0(SECOND_CLASS,Release,l)
  METHOD_RETURN(CLASS_RELEASE)
END_METHOD


; CLASS Constructor
CLASS_CONSTRUCTOR(SECOND_CLASS,FIRST_CLASS) ; Second class name is the one
                                            ; which should be extended
  VTABLE(SECOND_CLASS,SetCountry)
  VTABLE(SECOND_CLASS,GetCountry)
  VTABLE(SECOND_CLASS,Release)              ; Replace the Release() function of 
                                            ; FIRST_CLASS With new one
  CONSTRUCTOR_INIT(SECOND_CLASS)
  CLASS_DATA\Country = "Initial Country"
END_CONSTRUCTOR(SECOND_CLASS)
;=======================================================

;Test SECOND_CLASS
Debug "--------------------------------"
Debug "Test of SECOND_CLASS"
Debug "--------------------------------"
oClass2.IClass(SECOND_CLASS) = NEW_OBJECT(SECOND_CLASS)
Debug oClass2\GetName()
Debug oClass2\GetCountry()
oClass2\SetName("New Name")
oClass2\SetCountry("New Country")
Debug oClass2\GetName()
Debug oClass2\GetCountry()
Debug oClass2\Release()    ; returns #True if successful


;=======================================================
; Debuger output:

; --------------------------------
; Test of FIRST_CLASS
; --------------------------------
; Initial Name
; New Name
; 1
; --------------------------------
; Test of SECOND_CLASS
; --------------------------------
; Initial Name
; Initial Country
; New Name
; New Country
; 1
Die Makros und Funktionen in ClassTools.pbi basieren auf Danilos OOP Konzept, welches in seinen Beispielen zu finden ist:

=> Danilos OOP Beispiele

Einige Anmerkungen:
  • Two macros in one line ...
    Wenn das funktioniert, dann kann ich noch ein wenig vereinfachen (siehe auch Kommentare im Beispiel oben).
  • FreeStructureStrings as normal PB FUNCTION/COMMAND
    Wegen einem "Memory Leak" werden durch das Relase die Strings noch nicht freigegeben, weil sich diese in einer Struktur befinden, die dynamisch angelegt wurde. Ich hab' zwar einige Tests mit dem _SYS_FreeStructureStrings gemacht ... das führte aber immer wieder zu abstürzen.
  • Macro with wildcard for arguments
    Mit diesem Feature könnte ich noch einiges vereinfachen!
    Zur Zeit braiche ich noch die Makros METHOD_0, METHOD_1, METHOD_2, ... um Methoden mit 0, 1, 2 oder mehr Argumenten zu erstellen.
    Die aktuelle Include-Datei unterstützt zur Zeit auch nur NEW_OBJECT(ClassName) ohne Initialisierungs-Parameter. Das wäre mit "Wildcard argumenten recht einfach zu lösen.
Was denkt Ihr darüber?
Habt Ihr Vorschläge für Verbesserungen?

cu, helpy

[edit]
Download-Link für ClassTools.pbi hinzugefügt ... siehe oben.
[/edit]
Zuletzt geändert von helpy am 19.03.2006 21:32, insgesamt 4-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Include Datei mit Makros/Funktionen für OOP

Beitrag von ts-soft »

helpy hat geschrieben:Hallo

Ich habe eine Include-Datei
Schön, aber wie soll ich es testen, ohne diese?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Noch ein paar Anmerkungen (aus dem englischen Forum übersetzt):
remi_meier hat geschrieben:Eigentlich ist das für mich noch weniger lesbar.
Es stimmt! Das ist sicher gewöhnungsbedürftig!
Für mich ist es eine große Hilfe, das es weniger Tipp-Arbeit ist und nach dem man sich daran gewöhnt hat, auch übersichtlicher ist.
remi_meier hat geschrieben:... und einige Makros sind nur Wrapper für einzelne PureBasic Schlüsselworte.
Ja! Das ist richtig! Ich habe das so gemacht, weil es lesbarer ist wenn eine Methode mit METHOD_X beginnt auch mit END_METHOD endet.

Und der zweite Grund ist, dass ich in Zukunft "standard" Code für das aufräumen einer methode hinzufügen kann.
remi_meier hat geschrieben:Außerdem gibt es etwas Verwirrung (confusion) mit den Worten "define" und "declare" :wink: .
Das verstehe ich jetzt nicht ... aber vielleicht liegt das daran, dass englisch nicht meiner Muttersprache ist. Ich habe halt diese Makro-Namen DEFINE_CLASS und DEFINE_CLASS_DATA verwendet. Man kann das ja sehr einfach ändern.
remi_meier hat geschrieben:Wir sparen nicht einmal viel Tipparbeit durch diese Makros.
Nicht mit denen, die zur Zeit nur als Wrapper für PB-Schlüsselworte fungieren.

Aber ich habe noch die Idee einige Prüfungen einzubauen, durch welche man die gleiche Benennung von Klassen oder Methoden vermeidet. Diese Prüfungen würden entsprechende Compiler-Meldungen ausgeben ... und diese Prüfungen selbst würden letztlich auch keinen zusätzlichen Overhead im Programm-Code verursachen.

cu, helpy
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Für das define und declare hab ich dir leider nur diesen englischen Link:
http://en.wikipedia.org/wiki/Declaratio ... r_science)
Wichtigster Satz:
> Definitions reserve memory
> = Definitionen reservieren Speicher ;)
Das macht aber dein DEFINE_CLASS nicht, es sollte eher DECLARE_CLASS
heissen. Aber ist nur eine kleine Spitzfindigkeit <)

Ich finds schade, dass die Makros in PB noch so begrenzt sind, hab auch
mit sowas angefangen wie du aber schnell wieder aufgegeben, da ich
einfach so gut wie nichts gespart habe damit :roll:

Mach aber weiter so :allright:

greetz
Remi
Gesperrt