Danke hab mir jetzt mal folgendes gebastelt
Code: Alles auswählen
;-
;- Objekt erstellen
;-
Structure _testi_Instanz
*vtable
meins.l
EndStructure
Interface testi
_Create()
_Destroy()
Set(a.l)
Get()
EndInterface
Procedure _create(*obj._testi_Instanz)
Debug "...Neues Object erstellt"
EndProcedure
Procedure _destroy(*obj._testi_Instanz)
Debug "...Object zerstört"
EndProcedure
Procedure _Funk1(*obj._testi_Instanz,a.l)
*obj\meins=a
EndProcedure
Procedure _Funk2(*obj._testi_Instanz)
ProcedureReturn *obj\meins
EndProcedure
DataSection
_testi_function:
Data.i @_create()
Data.i @_destroy()
Data.i @_Funk1()
Data.i @_Funk2()
EndDataSection
;-
;- Macros zum Aufruf
;-
Macro OOPNew(vari,typ)
vari.typ, __#vari._#typ#_Instanz
If vari=0
vari=@__#vari
__#vari\vtable=?_#typ#_function
vari\_create()
EndIf
EndMacro
Macro OOPClear(vari,typ)
vari\_destroy()
FillMemory(@__#vari+SizeOf(vari), SizeOf(_#typ#_Instanz)-SizeOf(vari) )
vari\_create()
EndMacro
Macro OOPNewClear(vari,typ)
vari.typ, __#vari._#typ#_Instanz
If vari
vari\_destroy()
FillMemory(@__#vari+SizeOf(vari), SizeOf(_#typ#_Instanz)-SizeOf(vari) )
Else
vari=@__#vari
__#vari\vtable=?_#typ#_function
EndIf
vari\_create()
EndMacro
Macro OOPCopy(vari,varb)
CopyMemory(@__#vari,@__#varb,SizeOf(__#vari))
EndMacro
Macro OOPDelete(vari)
vari\_destroy()
vari=0
EndMacro
Macro OOPNewList(vari,typ,def=)
def NewList vari.typ()
def NewList __#vari._#typ#_Instanz()
EndMacro
Macro OOPAddElement(vari,typ)
AddElement(vari())
AddElement(__#vari())
vari()=@__#vari()
__#vari()\vtable=?_#typ#_function
vari()\_create()
EndMacro
Macro OOPDeleteElement(vari)
vari()\_destroy()
ChangeCurrentElement(__#vari(), vari())
DeleteElement(vari())
DeleteElement(__#vari())
EndMacro
Macro OOPClearList(vari)
ForEach vari()
vari()\_destroy()
Next
ClearList(vari())
ClearList(__#vari())
EndMacro
Macro OOPFirstElement(vari)
FirstElement(vari())
EndMacro
Macro OOPFreeList(vari)
ForEach vari()
vari()\_destroy()
Next
FreeList(vari())
FreeList(__#vari())
EndMacro
Macro OOPInsertElement(vari,typ)
InsertElement(vari())
InsertElement(__#vari())
vari()=@__#vari()
__#vari()\vtable=?_#typ#_function
vari()\_create()
EndMacro
Macro OOPLastElement(vari)
LastElement(vari())
EndMacro
Macro OOPListIndex(vari)
ListIndex(vari())
EndMacro
Macro OOPListSize(vari)
ListSize(vari())
EndMacro
Macro OOPNextElement(vari)
NextElement(vari())
EndMacro
Macro OOPPreviousElement(vari)
PreviousElement(vari())
EndMacro
Macro OOPResetList(vari)
ResetList(vari())
EndMacro
Macro OOPSelectElement(vari,b)
SelectElement(vari(),b)
EndMacro
Macro OOPChangeCurrentElement(vari,b)
ChangeCurrentElement(vari(),b)
EndMacro
Macro OOPSwapElements(vari,a,b)
SwapElements(vari(),a,b)
EndMacro
;-
;- beispiele
;-
Procedure AProc(b)
OOPNewList(AProList,testi,Static)
OOPClearList(AProList)
For i=1 To 10
OOPAddElement(AProList,testi)
AProList()\Set(b*I)
Next
ForEach AProList()
Debug AProList()\Get()
Next
EndProcedure
Debug "-"
Debug "- Static-Procedure-Test"
Debug "-"
Debug "Aufruf 1:"
AProc(1)
Debug "Aufruf 2:"
AProc(2)
Debug "-"
Debug "- Global List"
Debug "-"
OOPNewList(liste,testi,Global)
OOPAddElement(liste,testi)
liste()\set(1)
OOPAddElement(liste,testi)
liste()\set(2)
i=10
ForEach liste()
oopaddelement(Liste,testi)
liste()\set(i):i+1
Next
Debug "test1"
ForEach liste()
Debug liste()\get()
If liste()\get()=10
OOPDeleteElement(liste)
EndIf
Next
oopaddelement(liste,testi)
liste()\set(99)
Debug "test2"
ForEach liste()
Debug liste()\get()
Next
Debug "test3 - 10 sollte jetzt nicht mehr da sein"
ForEach __liste()
Debug __liste()\meins
Next
oopfreelist(liste)
Debug "----"
Define OOPnew(test,testi)
Define OOPnew(test2,testi)
Define OOPNew(test2,testi)
test\set(10)
test2\set(40)
Debug "--10,40"
Debug test\get()
Debug test2\get()
OOPCopy(test,test2)
Debug "--10,10"
Debug test\get()
Debug test2\get()
Debug "--10,30"
test2\set(30)
Debug test\get()
Debug test2\get()
OOPDelete(test)
OOPDelete(test2)
Die Macros sind so gestalltet, das man damit verschiedene "Interfaces" damit abdecken kann - wenn man die Namenskonventionen beibehält. Weiterer Vorteil: Automatischer Aufruf von _create() und vorallen _destroy(). Praktisch, wenn man Speicher oder andere Handles in den Objekt erstellt hat.
Größtes Problem an der ganzen Sache ist wohl, das PureBasic kein "_Destroy()" aufruft, wenn ein "OOP-Objekt" freigegeben wird. (Bspw. wenn es ein Protected-Variable innerhalb einer Prozedure ist) Das kann meiner Meinung nach zu einen bösen Speicherleck führen. Hier ist wirklich viel Programmierdisziplin gefordert. Meine Macros nutzen zumindest normale Variablen zum Speichern - wenn ein Objekt also keine Handles öffnet oder kein Speicher reserviert, dann gibts hier kein Speicherlecks...
Meine Empfehlung ist da wirklich, solche Objekte als Static oder Global zu benutzen - solange man eine Funktion nicht Rekursiv (=sich selbst aufrufend) braucht, sollte das kein Problem sein. Dann kann man einfach durch sowas:
Code: Alles auswählen
OOPNewList(AProList,testi,Static)
OOPClearList(AProList)
Sollten in der Liste noch von Letzen mal Objekte vorhanden sein, würden sie jetzt ordnungsgemäß freigegeben.
Genauso hier: Wenn es Meins schon gab, dann wird es freigeben und gelöscht und ein neues erstellt.
Was man halt auch wissen muss, bei den Macros wird immer eine zusatzvariable/liste mit __ an Anfang erstellt.