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
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 ;