Implémentation du comptage de références

Le comptage des références nécessite un travail de la part de l’implémenteur d’une classe et des clients qui utilisent des objets de cette classe. Lorsque vous implémentez une classe, vous devez implémenter les méthodes AddRef et Release dans le cadre de l’interface IUnknown . Ces deux méthodes ont les implémentations simples suivantes :

  • AddRef incrémente le nombre de références internes de l’objet.
  • Release commence par décrémenter le nombre de références internes de l’objet, puis vérifie si le nombre de références est tombé à zéro. Si c’est le cas, cela signifie que personne n’utilise plus l’objet , de sorte que la fonction Release libère l’objet.

Une approche d’implémentation courante pour la plupart des objets consiste à n’avoir qu’une seule implémentation de ces méthodes (avec QueryInterface), qui est partagée entre toutes les interfaces, et donc un nombre de références qui s’applique à l’objet entier. Toutefois, du point de vue d’un client, le comptage des références est strictement et clairement une notion de pointeur par interface, et par conséquent, les objets qui tirent parti de cette fonctionnalité en construisant, détruisant, chargeant ou déchargeant dynamiquement des parties de leurs fonctionnalités en fonction des pointeurs d’interface actuellement présents peuvent être implémentés. Il s’agit d’interfaces familièrement appelées « tear-off ».

Chaque fois qu’un client appelle une méthode (ou une fonction API), telle que QueryInterface, qui retourne un nouveau pointeur d’interface, la méthode appelée est chargée d’incrémenter le nombre de références via le pointeur retourné. Par exemple, lorsqu’un client crée un objet pour la première fois, il reçoit un pointeur d’interface vers un objet qui, du point de vue du client, a un nombre de références d’un. Si le client appelle ensuite AddRef sur le pointeur d’interface, le nombre de références devient deux. Le client doit appeler Release deux fois sur le pointeur d’interface pour supprimer toutes ses références à l’objet .

Un exemple de la façon dont les nombres de références sont strictement par pointeur d’interface se produit lorsqu’un client appelle QueryInterface sur le premier pointeur pour une nouvelle interface ou la même interface. Dans l’un ou l’autre de ces cas, le client doit appeler Release une fois pour chaque pointeur. COM n’exige pas qu’un objet retourne le même pointeur lorsque la même interface est demandée plusieurs fois. (La seule exception à cela est une requête à IUnknown, qui identifie un objet à COM.) Cela permet à l’implémentation de l’objet de gérer efficacement les ressources.

La sécurité des threads est également un problème important dans l’implémentation d’AddRef et release. Pour plus d’informations, consultez Processus, threads et appartements.

Gestion des durées de vie des objets via le comptage de références