Module oop und EnableClass
- NicTheQuick
- Ein Admin
- Beiträge: 8809
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Module oop und EnableClass
Ich muss zwar noch ein bisschen Refactoring betreiben, aber bisher sieht meine Implementierung so aus: classes.zip
In fast jeder Datei ist ein Beispiel dabei. Außerdem testet CLASS_TEST.pb das komplette Konstrukt. Wenn es keine Ausgabe gibt, dann funktioniert alles so, wie es soll. Es sind aber noch nicht alle Testcases und Möglichkeiten darin enthalten. Ihr könnt aber auch gerne damit herumspielen.
Ich habe mittlerweile das händische Hinzufügen der VirtualTable auch entfernt.
Edit:
Achja, wenn man "DebugLevel 10" benutzt, dann sieht man auch noch die Aufrufhierarchie der Konstrukturen und der Destruktoren und wann 'AllocateStructure()' und 'FreeStructure()' benutzt wird.
In fast jeder Datei ist ein Beispiel dabei. Außerdem testet CLASS_TEST.pb das komplette Konstrukt. Wenn es keine Ausgabe gibt, dann funktioniert alles so, wie es soll. Es sind aber noch nicht alle Testcases und Möglichkeiten darin enthalten. Ihr könnt aber auch gerne damit herumspielen.
Ich habe mittlerweile das händische Hinzufügen der VirtualTable auch entfernt.
Edit:
Achja, wenn man "DebugLevel 10" benutzt, dann sieht man auch noch die Aufrufhierarchie der Konstrukturen und der Destruktoren und wann 'AllocateStructure()' und 'FreeStructure()' benutzt wird.
Re: Module oop und EnableClass
@nic
Wenn ich das richtig sehe, wenn ein Child auf eine MemberVariable von Parent zugreifen will, muss es auch super benutzen, oder?
Das man beim Macro auch einen Parameterblock übergeben kann, auf die Idee bin ich nicht gekommen - blöd dass man nicht da einen Parameter reineditieren kann. Aber gute Idee.
Und das man nach einen CreateMacro-Macro ein : setzen muss, damit es weitergeht, war mir auch neu.... Warum auch immer.
edit: Kleiner Tipp, wenn man mit Createmacro ein Macro mit () erzeugt, kann man es mit UndefineMacro ohne () wieder "löschen".
also:
CreateMacro(__currentClass(),ClassName) :
UndefineMacro __currentClass
Wenn ich das richtig sehe, wenn ein Child auf eine MemberVariable von Parent zugreifen will, muss es auch super benutzen, oder?
Das man beim Macro auch einen Parameterblock übergeben kann, auf die Idee bin ich nicht gekommen - blöd dass man nicht da einen Parameter reineditieren kann. Aber gute Idee.
Und das man nach einen CreateMacro-Macro ein : setzen muss, damit es weitergeht, war mir auch neu.... Warum auch immer.
edit: Kleiner Tipp, wenn man mit Createmacro ein Macro mit () erzeugt, kann man es mit UndefineMacro ohne () wieder "löschen".
also:
CreateMacro(__currentClass(),ClassName) :
UndefineMacro __currentClass
Zuletzt geändert von GPI am 02.11.2015 17:42, insgesamt 1-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
- NicTheQuick
- Ein Admin
- Beiträge: 8809
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Module oop und EnableClass
Ja. Nenn es einen Nachteil, aber ich finde es nicht schlimm, wenn alle Member-Variablen automatisch private sind, solange man nicht superm() benutzt oder einen Getter dafür schreibt.GPI hat geschrieben:@nic
Wenn ich das richtig sehe, wenn ein Child auf eine MemberVariable von Parent zugreifen will, muss es auch super benutzen, oder?
Mir war es egal, ob man das 'this' bei jeder Methode noch hinschreibt oder nicht. Bei einigen Programmiersprachen ist das sowieso standard. Siehe z.B. Python.Das man beim Macro auch einen Parameterblock übergeben kann, auf die Idee bin ich nicht gekommen - blöd dass man nicht da einen Parameter reineditieren kann. Aber gute Idee.
Anders wollte es irgendwie nicht. Hauptsache es geht.Und das man nach einen CreateMacro-Macro ein : setzen muss, damit es weitergeht, war mir auch neu.... Warum auch immer.

- xXRobo_CubeXx
- Beiträge: 120
- Registriert: 12.06.2015 16:08
- Computerausstattung: Version 5.41 LTS
- Wohnort: Wohnort
- Kontaktdaten:
Re: Module oop und EnableClass
Was tut es? Hört sich nützlich anAchja, wenn man "DebugLevel 10" benutzt

Ja ich habe die Hilfe Seite gelsen aber die Beschreibung ist für mich nicht ausagekräftig genug und es gibt kein Code zum demonstrieren
Code: Alles auswählen
DebugLevel 2
Debug "hallo 1"
Debug "hallo 2"
Debug "hallo 3"
Debug "hallo 4"
Debug "hallo 5"
Debug "hallo 6"

Version 5.41 LTS 

Re: Module oop und EnableClass
probier mal
debug "testest",5
oder lies mal die Anleitung zu debug
debug "testest",5
oder lies mal die Anleitung zu debug

CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
- NicTheQuick
- Ein Admin
- Beiträge: 8809
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Module oop und EnableClass
Das hat eigentlich nichts mit diesem Thread zu tun, aber dennoch eine kurz Erklärung:
Debug "Text" wird immer ausgegeben.
Debug "Text", LEVEL nur dann, wenn man vorher mindestens DebugLevel LEVEL oder höher hingeschrieben hab.
So kann man sich verschiedene Debug-Stufen bauen, um nur grob oder feingranularer zu debuggen. Möchtest du an vielen Stellen in deinem Programm reichlich Informationen über "Debug" ausspucken, empfiehlt es sich, dahinter immer einen Level anzugeben. Da kann man gerne hoch ansetzen, also z.B. 10. Wichtigeren "Debug"-Ausgaben gibt man dann kleinere Level, also 9 abwärts. Später kann man dann die unwichtigen Debugs einfach ausschalten, indem man DebugLevel 9 setzt, weil man dann die ganzen "Debug"s mit Level 10 nicht mehr sieht, sondern nur noch die wichtigeren ab Level 9 abwärts.
Debug "Text" wird immer ausgegeben.
Debug "Text", LEVEL nur dann, wenn man vorher mindestens DebugLevel LEVEL oder höher hingeschrieben hab.
So kann man sich verschiedene Debug-Stufen bauen, um nur grob oder feingranularer zu debuggen. Möchtest du an vielen Stellen in deinem Programm reichlich Informationen über "Debug" ausspucken, empfiehlt es sich, dahinter immer einen Level anzugeben. Da kann man gerne hoch ansetzen, also z.B. 10. Wichtigeren "Debug"-Ausgaben gibt man dann kleinere Level, also 9 abwärts. Später kann man dann die unwichtigen Debugs einfach ausschalten, indem man DebugLevel 9 setzt, weil man dann die ganzen "Debug"s mit Level 10 nicht mehr sieht, sondern nur noch die wichtigeren ab Level 9 abwärts.
- xXRobo_CubeXx
- Beiträge: 120
- Registriert: 12.06.2015 16:08
- Computerausstattung: Version 5.41 LTS
- Wohnort: Wohnort
- Kontaktdaten:
Re: Module oop und EnableClass
Danke gpi und nicthequick 
Jetzt hab ich es verstanden

Jetzt hab ich es verstanden

Version 5.41 LTS 

Re: Module oop und EnableClass
Nenn es CharakterNicTheQuick hat geschrieben:Ja. Nenn es einen Nachteil, aber ich finde es nicht schlimm, wenn alle Member-Variablen automatisch private sind, solange man nicht superm() benutzt oder einen Getter dafür schreibt.

Ich hatte mich nur gewundert, wie du es mit Super hingebracht hast und das erklärts.
Mir geht es auch etwas um die Überprüfung. Ich möchte halt so viele Probleme wie möglich abfangen.Mir war es egal, ob man das 'this' bei jeder Methode noch hinschreibt oder nicht. Bei einigen Programmiersprachen ist das sowieso standard. Siehe z.B. Python.
Ich hab bei mir jetzt ein
Code: Alles auswählen
CompilerIf Not Defined(*self,#PB_Variable)
CompilerError "Missing 'This'!"
CompilerEndIf
Imo ein Bug in PB. Übrigens: Das Leerzeichen vor den Doppelpunkt ist auch wichtig!Anders wollte es irgendwie nicht. Hauptsache es geht.
Ich hab jetzt meine Variante hier hochgeladen: http://game.gpihome.eu/PureBasic/oop.7z
Mittlerweile bin ich recht flexibel, was die Klassenerstellung angeht:
Code: Alles auswählen
DeclareClass (cChild [,cParent] )
Get()
Set()
Properties
value.i
object.cIrgendwas
EndDeclareClass
[...]
Class (cChild [,options])
InitalizeObject(object, cIrgendwas [,Arraysize] )
Method (i, Initalize, (this,*initvalue) ); Konstruktor - ein Initalwert ist möglich
MethodReturn (xxx)
EndMethod
[....]
EndClass
Code: Alles auswählen
DeclareClass (cChild [,cParent] )
Get()
Set()
EndDeclareClass
[...]
Class (cChild [,options])
value.i
object.cIrgendwas
InitalizeObject(object, cIrgendwas [,Arraysize] )
Method (i, Initalize, (this,*initvalue) ); Konstruktor - ein Initalwert ist möglich
MethodReturn (xxx)
EndMethod
[....]
EndClass
Code: Alles auswählen
Interface cChild [ extends cParent]
Get()
Set()
EndInterface
InitalizeClass(cChild [,cParent] )
[...]
Class (cChild [,options])
value.i
object.cIrgendwas
InitalizeObject(object, cIrgendwas [,Arraysize] )
Method (i, Initalize, (this,*initvalue) ); Konstruktor - ein Initalwert ist möglich
MethodReturn (xxx)
EndMethod
[....]
EndClass
Code: Alles auswählen
Interface cChild [ extends cParent]
Get()
Set()
EndInterface
InitalizeClassEx(cChild [,cParent] )
value.i
object.cIrgendwas
EndInitalizeClassEx
[...]
Class (cChild [,options])
InitalizeObject(object, cIrgendwas [,Arraysize] )
Method (i, Initalize, (this,*initvalue) ); Konstruktor - ein Initalwert ist möglich
MethodReturn (xxx)
EndMethod
[....]
EndClass
Normalerweise würde ich sagen, das die Member-Variable-Definition eigentlich zur Klassendefinition gehört. Das funktioniert auch normalerweise wunderbar, es gibt aber eine große Ausnahme: Module (dazu gleich).
Folgende Class-Options gibt es:
oop::#AutoMutex - Jede Methode der Klasse wird automatisch mittels Mutex umschlossen
oop::#NoCreation - Verbietet die Benutzung der Klasse. Ist für Dummy-Klassen gedacht, die man nur erstellt, damit man sie als Parent nutzt.
oop::#NoChild - Die Klasse kann nicht als Parent benutzt werden. Wozu das gut sein soll? Keine Ahnung, aber ich hab mir überlegt, was man alles als Option nutzen kann

Der große Vorteil meines Codes ist, das es Modul-unabhängig ist. Man kann Klassen vollständig in Module-EndModule einfügen und die Klasse ist dann vollständig drin versteckt. Man kann auch die Klassen in Declare-Bereich declarieren und in "Rumpf" dann definieren. Eine Benutzung von außerhalb ist dann auch möglich mit modulename::klasse. Es gibt nur ein Problem: Eine solche Klasse kann nur ein als Parent dienen, wenn auch die Variablen in Declarations-Bereich sind. Darum die ganzen Varianten bei der Erstellung.
Mit Define_Object, Global_Object, Static_Object, Protected_Object werden Objecte erzeugt, die automatisch bei _ProcedureReturn, _EndProcedure und _End zerstört werden. Neu ist, das man einen InitalWert (integer oder halt Pointer) mitgeben kann. Mehr sind leider mit meiner Methode, wie ich die Klassen verwalte, nicht möglich. Notfalls kann man ja einen Pointer auf eine Struktur mitgeben. Meine Methode hier ist, das ich einen Default-Konstruktor habe, der immer aufgerufen wird und unabhängig von der Klasse ist. Der Ruft dann auch die Klassen-Initalize-Methode auf, sofern definiert.
Das "new" heißt bei mir AllocateObject() - damit wird ein freies Objekt erzeugt, das man selber mit FreeObject() wieder freigeben muss. CloneObject ist ähnlich, nur wird eine 1:1-Kopie des Objects erstellt (oder Null, falls es fehlschlägt).
Ansonsten gibts noch das CheckClass, CopyObject, ResetObject. Name sollte Programm sein.
Ich hab viel Wert auf Debug-Möglichkeiten gelegt. So werden, wenn der Debugger läuft, sämtliche Objekte in einer Liste erfasst. Bei _End werden dann alle nicht korrekt freigegeben Objekte aufgelistet und wo sie erzeugt werden. Zudem kann man mit DebugObject eine Meldung ausgeben, die auch die Objekterstellungsposition enthält. Bei der Klassenerstellung wird zudem kontrolliert, ob wirklich zu jeder Methode auch definiert wurde. Das passiert leider erst zur Laufzeit.
Das ganze wird aber nur mit eingeschalteten Debugger integriert, ansonsten ist es zugunsten der Geschwindigkeit und Speichernutzung ausge-compilerif-ed.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!