Macro de simplification POO

Partagez votre expérience de PureBasic avec les autres utilisateurs.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Macro de simplification POO

Message par nico »

La macro que je vous propose permet de rajouter les opérateurs New et Delete.

Code : Tout sélectionner

; Fichier New_Delete.pb

Macro New(Pointer,Class)
  Pointer#_.Class#_=AllocateMemory(SizeOf(Class#_))
  Pointer#_\Vtable=?Class
  Pointer#.Class=@Pointer#_\Vtable
  Class(Pointer)
EndMacro

Macro Delete(Pointer,Class)
  Pointer#_.Class#_=Pointer
  Class#_(Pointer)
  FreeMemory(Pointer)
EndMacro

Un test:

Code : Tout sélectionner

; Important:pour que la macro fonctionne, il est impératif
; - Que le nom de la structure soit le même que le nom de l'interface suivit du caractère "_"
; - Que la structure possède la variable Vtable (Première position dans la structure important)
; - Que les procédures Constructeur et Destructeur possèdent le même nom que celui de l'interface
; - Que le nom de chargement des données dans la DataSection soit le même que celui de l'interface

; Pour Rappel: *This = Adresse de la variable Vtable

; Il est important que cette variable Vtable soit déclaré en premier
; dans la Structure pour que: *This.Calcul_=*This.Calcul
; SiVtable était déclaré en deuxième position, on aurait:*This.Calcul_=*This.Calcul-8

; Cela nous permet donc de remplacer dans les procédures *This.Calcul par *This.Calcul_
; On choisit ainsi de travailler sur les fonctions ou sur les membres en prenant l'un ou l'autre



; Fonctions de la Classe
Interface Calcul
    SetData(a.l,b.l)
    Addition()
    Multiplication()
EndInterface

; Membre de la classe
Structure Calcul_
    Vtable.l      ; Important première position
    a.l 
    b.l
EndStructure

; Constructeur de la Classe
; Appelé aprés création des ressources
Procedure Calcul(*This.Calcul_)
  Debug "--------------------------"
  Debug "Constructor"
  *This\a=0
  *This\b=0
  Debug "--------------------------"
EndProcedure

; Destructeur de la Classe
; Appelé avant libération des ressources
Procedure Calcul_(*This.Calcul_)
  Debug "--------------------------"
  Debug "Destructor"
  Debug "--------------------------"
EndProcedure

IncludeFile "New_Delete.pb"

Procedure.l Setdata(*This.Calcul_,a.l,b.l)
  *This\a=a
  *This\b=b
EndProcedure

Procedure.l Addition(*This.Calcul_)
    ProcedureReturn *This\a + *This\b
EndProcedure

Procedure.l Multiplication(*This.Calcul_)
    ProcedureReturn *This\a * *This\b
EndProcedure

New(*Pointeur,Calcul)
*Pointeur\Setdata(5,3)

Debug "Addition= "+Str(*Pointeur\ Addition())
Debug "Multiplication= "+Str(*Pointeur\ Multiplication())

Delete(*Pointeur,Calcul)


DataSection
Calcul:
Data.l @SetData(),@Addition(),@Multiplication()
EndDataSection
Anonyme

Message par Anonyme »

y a pas un bug ici ?

Macro New(Pointer,Class)
Pointer#_.Class#_=AllocateMemory(SizeOf(Class#_))
Pointer#_\Vtable=?Class
Pointer#.Class=@Pointer#_\Vtable
Class(Pointer)
EndMacro

Macro Delete(Pointer,Class)
Pointer#_.Class#_=Pointer
Class#_(Pointer)
FreeMemory(Pointer)
EndMacro

Class() Fait quoi exactement ?
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Toute la difficulté des macro est de comprendre qu'on lui passe du texte en paramètre et pas des valeurs.

il faut donc remplacer Class par Calcul et Pointer par Pointeur

et on obtient ça:

Code : Tout sélectionner

*Pointeur_.Calcul_=AllocateMemory(SizeOf(Calcul_))
*Pointeur_\Vtable=?Calcul
*Pointeur.Calcul=@*Pointeur_\Vtable
Calcul(*Pointeur)


*Pointeur_.Calcul_=*Pointeur
Calcul_(*Pointeur)
FreeMemory(*Pointeur)
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

La nouvelle macro

Code : Tout sélectionner

;-----------------------Fichier New_Delete.pb --------------------

Macro Class(Debut)
  Interface Debut
EndMacro

Macro Membre(Fin)
  EndInterface
  Structure Fin#_
  Vtable.l 
EndMacro

Macro EndClass()
  EndStructure
EndMacro


Macro New(Pointer,Class)
  Pointer#_.Class#_=AllocateMemory(SizeOf(Class#_))
  Pointer#_\Vtable=?Class
  Pointer#.Class=@Pointer#_\Vtable
  Class(Pointer)
EndMacro

Macro Delete(Pointer,Class)
  If Pointer
    Pointer#_.Class#_=Pointer
    Class#_(Pointer)
    FreeMemory(Pointer)
  EndIf 
EndMacro

Macro Method(Class,Function)
    Procedure.l Function#(*This.Class#_
EndMacro 


Macro Constructor(Class)
    Procedure.l Class#(*This.Class#_)
EndMacro 


Macro Destructor(Class)
    Procedure.l Class#_(*This.Class#_)
EndMacro 

Macro Close()
  EndProcedure
EndMacro 
;-----------------------------------------------------------------

Un Test:

Code : Tout sélectionner

IncludeFile "New_Delete.pb" 

Class(Calcul)

  SetData(a.l,b.l)
  Addition()
  Multiplication()
  
  Membre(Calcul)
  a.l
  b.l
EndClass() 


Constructor(Calcul)
  Debug "--------------------------"
  Debug "Constructor"
  *This\a=0
  *This\b=0
  Debug "--------------------------"
Close()


Destructor(Calcul)
  Debug "--------------------------"
  Debug "Destructor"
  Debug "--------------------------"
Close()


Method(Calcul,Setdata),a.l,b.l)
  *This\a=a
  *This\b=b
Close()

Method(Calcul,Addition))
    ProcedureReturn *This\a + *This\b
Close()

Method(Calcul,Multiplication))
    ProcedureReturn *This\a * *This\b
Close()

New(*Pointeur,Calcul)
*Pointeur\Setdata(5,3)

Debug "Addition= "+Str(*Pointeur\ Addition())
Debug "Multiplication= "+Str(*Pointeur\ Multiplication())

Delete(*Pointeur,Calcul)


DataSection
Calcul:
Data.l @SetData(),@Addition(),@Multiplication()
EndDataSection
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Excellent, j'aime bien la syntaxe. :)

Par contre, il semble que tu n'ai pas un accès direct au données interne
à la classe, genre *pointeur\a = 0 .

J'ai pas essayé si il était possible de faire une fonction héritée..
Force et sagesse...
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

On ne peut pas avoir à la fois accès aux membres et aux fonctions avec un seul pointeur, c'est comme ça pour faire de la POO avec Pb.

Pour manipuler directement les membres il faut faire par exemple:

Code : Tout sélectionner

; Automatiquement le code génère la structure Calcul +tiret bas qui donne accès aux membres
New(*Pointeur,Calcul)
*pointeur2.calcul_=*pointeur
*pointeur2\a=10
*pointeur2\b=8
Pour l'héritage, on ne peut le faire qu'ave les interfaces, un exemple en rajoutant la soustraction:

Code : Tout sélectionner

Interface Soustraction
  Soustraction()
EndInterface 


Class(Calcul Extends Soustraction)
  SetData(a.l,b.l)
  Addition()
  Multiplication()
  
  Membre(Calcul)
  a.l
  b.l
EndClass() 


Constructor(Calcul)
  Debug "--------------------------"
  Debug "Constructor"
  *This\a=0
  *This\b=0
  Debug "--------------------------"
Close()


Destructor(Calcul)
  Debug "--------------------------"
  Debug "Destructor"
  Debug "--------------------------"
Close()


Method(Calcul,Soustraction))
  ProcedureReturn *This\a - *This\b
Close()

Method(Calcul,Setdata),a.l,b.l)
  *This\a=a
  *This\b=b
Close()

Method(Calcul,Addition))
    ProcedureReturn *This\a + *This\b
Close()

Method(Calcul,Multiplication))
    ProcedureReturn *This\a * *This\b
Close()

New(*Pointeur,Calcul)

;Modification des valeurs en passant par une fonction
;/*Pointeur\Setdata(5,3)

; Modification directe des valeurs
*pointeur2.calcul_=*pointeur
*pointeur2\a=5
*pointeur2\b=3


Debug "Addition= "+Str(*Pointeur\ Addition())
Debug "Multiplication= "+Str(*Pointeur\ Multiplication())
Debug "Multiplication= "+Str(*Pointeur\ Soustraction())

Delete(*Pointeur,Calcul)

DataSection
Calcul:
Data.l @Soustraction(),@SetData(),@Addition(),@Multiplication()
EndDataSection
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

OK, merci pour les précisions. J'ai pas mal appris avec ton code et tes macro,
je vais adapter le mien pour le rendre plus 'présentable' et
souple. (cf post "POO façon maison")

:wink:
Force et sagesse...
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

C'est assez énorme... !
Bravo nico !!!! :lol:

Lip
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Répondre