Page 1 sur 1

Macro de simplification POO

Publié : mer. 18/juil./2007 10:21
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

Publié : jeu. 19/juil./2007 2:09
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 ?

Publié : jeu. 19/juil./2007 13:56
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)

Publié : sam. 28/juil./2007 22:00
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

Publié : dim. 29/juil./2007 8:57
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..

Publié : dim. 29/juil./2007 10:57
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

Publié : dim. 29/juil./2007 11:04
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:

Publié : mar. 07/août/2007 9:44
par lionel_om
C'est assez énorme... !
Bravo nico !!!! :lol:

Lip