Identification et instanciation des objets

De RAD Studio
Aller à : navigation, rechercher

Remonter à Modèles C++ et Pascal Objet


En C++, une instance d’une classe est un objet effectif. Cet objet peut directement être manipulé et il est possible d’y accéder indirectement via une référence ou un pointeur.

Par exemple, étant donné une classe C++ CPP_class utilisant un constructeur sans argument, le code suivant définit des variables d’instance valides de cette classe :
 CPP_class by_value;// an object of type CPP_clas s 
 CPP_class& ref = by_value;// a reference to the object by_value, abov e 
 CPP_class* ptr =  new  CPP_class();// a pointer to an object of type CPP_clas s

Par contre, en Pascal Objet, une variable de type objet désigne toujours l’objet indirectement. La mémoire de tous les objets est allouée dynamiquement. Par exemple, étant donné une classe Pascal Objet OP_class

 ref: OP_class ; 
 ref := OP_class.Create ;
ref is a reference to an object of type OP_class.
Translated to C++Builder code, it would be
 OP_class* ref =  new  OP_class;

Différences entre les références C++ et Pascal Objet

La documentation désigne fréquemment une variable d’instance de classe Pascal Objet sous le terme de référence, mais décrit son comportement comme celui d’un pointeur. C’est qu’elle a à la fois les propriétés des deux. Une référence d’objet en Pascal Objet est similaire à un pointeur C++ avec les exceptions suivantes :

  • Une référence Pascal Objet est implicitement déréférencée (elle se comporte alors davantage comme une référence C++).
  • Une référence Pascal Objet n’a pas d’arithmétique de pointeur définie.

Quand on compare une référence Pascal Objet et une référence C++, il y a également des similitudes et des différences. Les références sont déréférencées implicitement dans les deux langages, mais :

  • Une référence Pascal Objet peut être réassociée alors qu’une référence C++ ne peut pas l’être.
  • Une référence Pascal Objet peut valoir nil, alors qu'une référence C++ doit désigner un objet valide.

Certaines décisions de conception sous-jacentes aux frameworks FireMonkey et RTL dépendent de l'utilisation de ce type de variables d'instance. Un pointeur est la construction du langage C++ la plus proche d’une référence en Pascal Objet. De ce fait, presque tous les identificateurs d’objet FireMonkey et RTL sont traduits en pointeurs C++ dans C++Builder.

Remarque: Le type de paramètre var Object Pascal est une correspondance étroite pour une référence C++.

Copie d’objets

A la différence de C++, Pascal Objet ne dispose pas d’une gestion par le compilateur de la copie d’objets. Cette section décrit les effets de cette différence sur les opérateurs d’affectation et les constructeurs de copie dans les classes de style Delphi.

Opérateurs d'affectation

L’opérateur d’affectation Pascal Objet (:=) n’est pas un opérateur d’affectation de classe (opérateur=()). L’opérateur d’affectation copie la référence et non l’objet. Ainsi, dans le code suivant, B et C désignent tous deux le même objet :

 B, C: TButton ; 
 B:= TButton.Create(ownerCtrl) ; 
 C:= B ;

Cet exemple se traduit dans le code C++Builder suivant :

 TButton *B = NULL ; 
 TButton *C = NULL ; 
 B = new TButton(ownerCtrl) ; 
 C = B;// makes a copy of the pointer, not the object

Les classes de style Delphi en C++Builder suivent les règles du langage Pascal Objet pour les opérateurs d’affectation. Cela signifie que dans le code suivant, les affectations entres les pointeurs déréférencés ne sont pas valides car elles tentent de copier l’objet et pas le pointeur :

 TRTLStyleClass *p =  new  TRTLStyleClass ; 
 TRTLStyleClass *q =  new  TRTLStyleClass ; 
 *p = *q;// not allowed for Delphi style class objects

Remarque : Pour les classes de style Delphi, il est légal d’utiliser une syntaxe C++ pour lier à une référence. Par exemple, le code suivant est correct :

 TRTLStyleClass *ptr =  new  TRTLStyleClass ; 
 TRTLStyleClass &ref = *ptr;// OK for Delphi style classes

Bien que cela soit différent de l’utilisation d’un opérateur d’affectation, la syntaxe est suffisamment semblable pour la mentionner ici à titre de comparaison.

Constructeurs de copie

Pascal Objet n’a pas de constructeurs de copie intégrés. De ce fait, les classes de style Delphi de C++Builder n’ont pas de constructeurs de copie prédéfinis. L’exemple de code suivant tente de créer un pointeur TButton en utilisant un constructeur de copie :

 TButton *B =  new  TButton(ownerCtrl) ; 
 TButton *C =  new  TButton(*B);// not allowed for Delphi style class object s

N'écrivez pas de code dépendant d'un constructeur de copie intégré pour les classes Delphi. Pour créer une copie d’un objet d’une classe de style Delphi avec C++Builder, vous pouvez écrire le code d’une fonction membre copiant cet objet. Sinon, les descendants de la classe RTL TPersistent peuvent redéfinir la méthode Assign pour copier les données d'un objet dans un autre. Cela se fait, par exemple, dans les classes graphiques FMX comme TBitmap et TIcon qui contiennent des ressources image. Enfin, la manière de copier un objet peut être déterminée par le programmeur (le concepteur de composants) ; mais il faut faire attention car certaines méthodes de copie utilisées en C++ standard ne sont pas utilisables pour les classes de style Delphi.

Utilisation d’objets comme arguments de fonction

Comme indiqué, les instances de variables diffèrent en C++ et en Pascal Objet. Vous devez en tenir compte quand vous transmettez des objets comme arguments de fonctions. En C++, les objets peuvent être transmis aux fonctions par valeur, par référence ou par pointeur. Dans Pascal Objet, quand un objet est transmis par valeur à une fonction, souvenez-vous que l’argument objet est déjà une référence à un objet. C’est donc la référence qui est transmise par valeur et non pas l’objet lui-même. Il n’y a pas d’équivalent en Pascal Objet au transfert par valeur réelle d’un objet comme cela peut se faire en C++. Les objets de style Delphi transmis à des fonctions suivent les règles Pascal Objet.

Voir aussi