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

Für allgemeine Fragen zur Programmierung mit PureBasic.
puretom
Beiträge: 109
Registriert: 06.09.2013 22:02

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

Beitrag 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()

Windows 7 und Windows 10 (Laptop), PB 5.62 | Projekt: Tutorial - Compiler und Virtual Machine | vielleicht einmal ein Old School Text-Adventure Tutorial | Neu: Spielereien, Üben rund um OOP in PB
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

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

Beitrag 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...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
puretom
Beiträge: 109
Registriert: 06.09.2013 22:02

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

Beitrag 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?
Windows 7 und Windows 10 (Laptop), PB 5.62 | Projekt: Tutorial - Compiler und Virtual Machine | vielleicht einmal ein Old School Text-Adventure Tutorial | Neu: Spielereien, Üben rund um OOP in PB
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

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

Beitrag 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()

Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
puretom
Beiträge: 109
Registriert: 06.09.2013 22:02

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

Beitrag 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?
Windows 7 und Windows 10 (Laptop), PB 5.62 | Projekt: Tutorial - Compiler und Virtual Machine | vielleicht einmal ein Old School Text-Adventure Tutorial | Neu: Spielereien, Üben rund um OOP in PB
Antworten