Accès au variables privées d’une

objet sous Delphi

 

 Rappels :

Un objet est une instance d’une classe.

Sous delphi, les variables placées dans la partie Private d’une classe
ne sont accessibles qu’à l’intérieur de l’unité ou la classe est définie.

Les variables placées dans la partie Protected sont accessibles à l’intérieur de l’unité où la
classe est définie et dans les unités ou une classe dérivée est définie.

Les variables placées dans la partie Public sont accessibles partout.

 

D’une manière générale on ne doit pas accéder aux variables privées d’un
objet et on ne peut d’ailleurs pas le faire. Un objet doit en effet être une boîte
noire (ayant un état, un comportement fonction de cette état et une identité) à
laquelle on accède par son interface (partie Public et Published). Cela permet
par exemple de complètement modifier la boîte noire interne de la classe
dans de nouvelles versions et de n’avoir à modifier que cette boite noire du moment que l’on
conserve l’interface. Cela permet aussi de maintenir des données internes cohérentes
par rapport au comportement de l’objet.

Il arrive toutefois des cas où le code d’une classe de la VCL de delphi ne nous
convient pas et qu’un accès à la partie privée d’une classe résolve tout au risque de ne pas être
compatible avec les versions futures de Delphi…

On peut assez simplement accéder aux variables privées d’une classe depuis n’importe quelle
unité. L’accès aux fonctions privées n’étant lui pas simplement possible.

Si l’on a par exemple une classe TVache définit comme suit :

TVache = class
Private

FCri : string ;
Procedure ……
Public
sPetitNom : string ;
End ;

avec FCri fixé à ‘MEUH’ à la création de TVache et
deux instances de cette classe appelées vaNoireaude et vaMarguerite ayant
pour petit nom respectif ‘La Noireaude’ et ‘Marguerite’.

Avec Delphi, cela nous donne en mémoire :

 

Delphi crée pour chaque instance d’une classe l’équivalent d’un tableau de variables dont
la première entrée référence la Virtual Memory Table contenant le mécanisme de pointage des
méthodes de la classe.

Si maintenant on a la classe

 TPublicVache = class

Public

FCri : string ;

sPetitNom : string ;

Procedure ……

End ;

 

Avec les mêmes données que précédemment, c’est à dire
avec FCri fixé à ‘MEUH’ à la création de TPublicVache et
deux instances de cette classe appelées vaNoireaude et vaMarguerite ayant
pour petit nom respectif ‘La Noireaude’ et ‘Marguerite’.

On a alors en mémoire :

 

Concernant les variables on a la même chose en mémoire. Tout se passe
comme s’il y avait un masque pour accéder aux variables.

Dans notre exemple on aurait :

Masque d’accès à une instance de TVache :

 

Masque d’accès à une instance de TPublicVache :

 

Donc, pour accéder aux variables privées d’un objet, il suffit d’accéder à sa représentation
en mémoire en utilisant le masque d’une classe ayant la même représentation en mémoire
mais n’ayant que des variables public. Cela revient en fait a ‘caster’ la dite classe.

Exemple :

 

Unit Vache ;

 

TVache = class

Private

FCri : string ;

Procedure ……

Public

sPetitNom : string ;

End ;

 

 

Unit principale ;

 

 

TCrackVache = class

Public

FCri : string ;

sPetitNom : string ;

End ;

 

 

implementation

 

var LaNoireaude : Tvache ;

 

 

……..

 

procedure VacheToCanard ;

begin

//-- on caste l’intance la noireaude en TcrackVache

//-- pour accéder à sa variable privée FCri

TcrackVache(LaNoireaude).FCri := ‘CoinCoin’ ;

End ;