Seite 1 von 1

Module-Vorlage für ein einfaches Objekt (OOP)

Verfasst: 09.06.2018 11:45
von puretom
Hab für mich eine Vorlage (Template) für ein einfaches Objekt (also für OOP) gemacht.
Mit Beispielcode.

Teil ich mal mit euch.


Falls wer Fehler findet, bitte Feedback.
Falls ich Begriffsverwirrung habe, bitte auch Feedback, bin mit all den Begriffen rund um OOP nicht so 100% sattelfest.

LG Thomas

Code: Alles auswählen


Interface Passenger
  
  
  ; Object's Public Instance Methods, we need Interface
  ;
  GetIdNumber.i()    
  
  ; Free is a Public Instance Procedure, we need Interface
  ;
  Free.i() 
    
EndInterface
DeclareModule Passenger
  
  ; new is a Public Class Procedure, no Interface needed
  ;
  Declare.i New(ParamIdNumber)
  
EndDeclareModule
Module Passenger
  EnableExplicit
  
  ; Object's Private Instance Fields/Variables
  ;
  Structure object
    
    ; Points to Pointer Table to Public Instance Methods in Data Section
    ;
    *_method_table_ 
    
    ; Put your Private Instance Fields/Variables variables here
    ;
    
    ; test code
    IdNumber.i
    
  EndStructure
    
  ; Generic Constructor
  ;
  Procedure Construct(object_name.s)
    
    ; with security check
    ;
    Protected *new.object = AllocateStructure(object)
    If *new
      *new\_method_table_ = ?method_table
    Else
      MessageRequester("Runtime Class Allocation Error","Allocation of Object '"+object_name+"' failed.")
      End
    EndIf
    
    ProcedureReturn *new
    
  EndProcedure
  
  ; ****  Put your Code starting here  **************************************************
  ;
  
  ; Constructor(s), Destructor(s)
  ;
  Procedure New(ParamIdNumber)
    
    Protected *this.object
    
    ; Call generic Constructor
    ;
    *this = Construct("Passenger")
    
    ; Put more individual construction code here
    ;    
    
    ; test code
    *this\IdNumber = ParamIdNumber
    
    
    ; Give back the Pointer to Instance
    ;
    ProcedureReturn *this
    
  EndProcedure
  Procedure Free(*this.object)
    
    ; Use generic FreeStructure to destruct object
    ;
    FreeStructure(*this)
    
    ; Put more individual destruction code here
    ;    
    
    ; give back a zero pointer 
    ;
    ProcedureReturn 0
    
  EndProcedure
  
  ; Others
  ;
  Procedure GetIdNumber(*this.object)
    
    ProcedureReturn *this\IdNumber
    
  EndProcedure
  
  ; Pointer Table to Public Instance Methods
  ;
  DataSection
    method_table:
    Data.i @GetIdNumber()
    Data.i @Free()
  EndDataSection
  
EndModule

; Test Code



; Interface name and Module name are allowed to be the same
;
; Pointer to Instance        Module name
;    |                         |
;    |    Interface name       |
;    |         |               |
;    v         v               v
Passenger11.Passenger = Passenger::New(11)
Debug "Pointer to Object Instance 'Passenger11': "+Passenger11 

Passenger22.Passenger = Passenger::New(22)
Debug "Pointer to Object Instance 'Passenger22': "+Passenger22 

Passenger44.Passenger = Passenger::New(44)
Debug "Pointer to Object Instance 'Passenger44': "+Passenger44 


;                                     Pointer to Instance         Instance Procedure
;                                                    |               |             
;                                                    |               |             
;                                                    v               v             
Debug "IdNumber of Object Instance 'Passenger44': "+Passenger44\GetIdNumber()
Debug "IdNumber of Object Instance 'Passenger22': "+Passenger22\GetIdNumber()
Debug "IdNumber of Object Instance 'Passenger11': "+Passenger11\GetIdNumber()

; Destroy it again
;
Passenger11 = Passenger11\Free()
Debug "Pointer to DESTROYED 'Passenger11': "+Passenger11 

; should flag error because instance was destroyed
; Debug "IdNumber of Object Instance 'Passenger11': "+Passenger11\GetIdNumber()


Re: Module-Vorlage für ein einfaches Objekt (OOP)

Verfasst: 09.06.2018 14:00
von mk-soft
Im Prinzip die Richtung schon richtig.

Vielleicht hilft dir das ein wenig weiter!
Link: viewtopic.php?f=9&t=30603

Wenn du eine Basis für OOP suchst, dann schau dir vielleicht mal die OOP-BaseClass mal an.
Siehe Signatur...

Re: Module-Vorlage für ein einfaches Objekt (OOP)

Verfasst: 09.06.2018 14:26
von puretom
Danke fürs Feedback.
mk-soft hat geschrieben:Im Prinzip die Richtung schon richtig.
Habe ich noch etwas vergessen?
Erzeuge ich Speicherlecks beim "Destroy" oder passt das alles?

Wenn die "Richtung stimmt", dann interpretiere ich in deine Aussage, dass das noch nicht ganz passen kann <)

Edit: Du kannst ja Vererbung und noch tollere Sachen. Mir geht es eigentlich nur um ein einfache Basis-Klasse, mit der ich recht einfach mehrere Objekte/Instanzen erzeugen kann. Dann bin ich schon glücklich.
Passt das so für diesen Zweck, was ich da an Code zusammengeschustert habe?

Re: Module-Vorlage für ein einfaches Objekt (OOP)

Verfasst: 09.06.2018 17:23
von mk-soft
Ich alles gut :wink:

Kleiner Tipp
Du kannst für den Namen für von dein Objekt auch den Module-Name verwenden...

Code: Alles auswählen

Procedure Construct()
    
    ; with security check
    ;
    Protected *new.object = AllocateStructure(object)
    If *new
      *new\_method_table_ = ?method_table
      Debug "New " + #PB_Compiler_Module
    Else
      MessageRequester("Runtime Class Allocation Error","Allocation of Object '"+ #PB_Compiler_Module +"' failed.")
      End
    EndIf
    
    ProcedureReturn *new
    
  EndProcedure
Ich finde es besser wenn das Interface auch in DeclareModule sich befindet. Das ist aber Geschmacksache ...

Code: Alles auswählen

DeclareModule Passenger
  
  Interface iPassenger
    
    
    ; Object's Public Instance Methods, we need Interface
    ;
    GetIdNumber.i()    
    
    ; Free is a Public Instance Procedure, we need Interface
    ;
    Free.i() 
      
  EndInterface
  
  ; new is a Public Class Procedure, no Interface needed
  ;
  Declare.i New(ParamIdNumber)
  
EndDeclareModule
Module Passenger
  EnableExplicit
  
  ; Object's Private Instance Fields/Variables
  ;
  Structure object
    
    ; Points to Pointer Table to Public Instance Methods in Data Section
    ;
    *_method_table_ 
    
    ; Put your Private Instance Fields/Variables variables here
    ;
    
    ; test code
    IdNumber.i
    
  EndStructure
    
  ; Generic Constructor
  ;
  Procedure Construct()
    
    ; with security check
    ;
    Protected *new.object = AllocateStructure(object)
    If *new
      *new\_method_table_ = ?method_table
      Debug "New " + #PB_Compiler_Module
    Else
      MessageRequester("Runtime Class Allocation Error","Allocation of Object '"+ #PB_Compiler_Module +"' failed.")
      End
    EndIf
    
    ProcedureReturn *new
    
  EndProcedure
  
  ; ****  Put your Code starting here  **************************************************
  ;
  
  ; Constructor(s), Destructor(s)
  ;
  Procedure New(ParamIdNumber)
    
    Protected *this.object
    
    ; Call generic Constructor
    ;
    *this = Construct()
    
    ; Put more individual construction code here
    ;    
    
    ; test code
    *this\IdNumber = ParamIdNumber
    
    
    ; Give back the Pointer to Instance
    ;
    ProcedureReturn *this
    
  EndProcedure
  Procedure Free(*this.object)
    
    ; Use generic FreeStructure to destruct object
    ;
    FreeStructure(*this)
    
    ; Put more individual destruction code here
    ;    
    
    ; give back a zero pointer 
    ;
    ProcedureReturn 0
    
  EndProcedure
  
  ; Others
  ;
  Procedure GetIdNumber(*this.object)
    
    ProcedureReturn *this\IdNumber
    
  EndProcedure
  
  ; Pointer Table to Public Instance Methods
  ;
  DataSection
    method_table:
    Data.i @GetIdNumber()
    Data.i @Free()
  EndDataSection
  
EndModule

; Test Code



; Interface name and Module name are allowed to be the same
;
; Pointer to Instance        Module name
;    |                         |
;    |    Interface name       |
;    |         |               |
;    v         v               v
Passenger11.Passenger::iPassenger = Passenger::New(11)
Debug "Pointer to Object Instance 'Passenger11': "+Passenger11 

Passenger22.Passenger::iPassenger = Passenger::New(22)
Debug "Pointer to Object Instance 'Passenger22': "+Passenger22 

Passenger44.Passenger::iPassenger = Passenger::New(44)
Debug "Pointer to Object Instance 'Passenger44': "+Passenger44 


;                                     Pointer to Instance         Instance Procedure
;                                                    |               |             
;                                                    |               |             
;                                                    v               v             
Debug "IdNumber of Object Instance 'Passenger44': "+Passenger44\GetIdNumber()
Debug "IdNumber of Object Instance 'Passenger22': "+Passenger22\GetIdNumber()
Debug "IdNumber of Object Instance 'Passenger11': "+Passenger11\GetIdNumber()

; Destroy it again
;
Passenger11 = Passenger11\Free()
Debug "Pointer to DESTROYED 'Passenger11': "+Passenger11 

; should flag error because instance was destroyed
; Debug "IdNumber of Object Instance 'Passenger11': "+Passenger11\GetIdNumber()


Re: Module-Vorlage für ein einfaches Objekt (OOP)

Verfasst: 09.06.2018 19:15
von puretom
Danke für den Tip mit dem Modulnamen.

Code: Alles auswählen

Passenger11.Passenger = Passenger::New(11)
erscheint mir schlüssiger und vor allem kürzer als

Code: Alles auswählen

Passenger11.Passenger::iPassenger = Passenger::New(11)
Immerhin ein Wort weniger und ich bin (tipp)faul wie das Tier in meinem Avatarbild. :lol:

Ist aber wie gesagt syntaktische Geschmackssache.

Sonst passt alles?

Wenn ich mal Zeit habe, sollte ich mir das Compilat anschauen.
Hast du das gemacht?
Wieviel Overhead erzeugen wir mit dieser Art von Code?