Règles de comptage de référence

Traductions disponibles Traductions disponibles
Numéro d'article: 104138 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Dans le modèle d'objet composant, la durée de vie d'une interface est contrôlée par l'intermédiaire de décompte de références. Le décompte de références pour une interface est manipulé via les fonctions de membre AddRef() et Release() héritées de IUnknown. Le membre AddRef() incrémente le décompte de références d'une interface et la méthode Release() décrémente il. Une fois le décompte de références d'une interface atteint zéro, il n'y a plus tous les pointeurs valides à cette interface. Si le décompte de références sur toutes les interfaces d'un objet est égal à zéro, l'objet peut être libérée, car il n'y a plus tous les pointeurs à l'objet.

Plus d'informations

Règles de comptage de référence

La liste suivante est une copie de la référence règles (issues de pages 83 et 84 de la spécification de OLE 2.0) qui doivent être suivis d'inventaire. Exemples de code petit ont été ajoutés dans cet article pour clarifier les règles.

  1. Chaque nouvelle copie d'un pointeur d'interface doit être AddRef () d, et chaque destruction d'un pointeur d'interface doit être Release () auriez sauf où les règles suivantes autorisent explicitement dans le cas contraire.

    1. Paramètres de sortie aux fonctions : l'appelant doit AddRef() le véritable paramètre, car il sera Release () d par l'appelé lorsque l'out-value est stocké du dessus.
            LPOLEOBJECT lpObject;
               .
               .  // Get pointer to IOleObject.
               .
            LPVIEWOBJECT lpView = lpObject;
      
            lpObject->AddRef()
      
            // GetViewObject is a theoretical function that takes a
            // pointer to anything derived from IUnknown, and then
            // returns a pointer to IViewObject in the same variable
            // passed as the parameter. The AddRef() above is needed so
            // that the original pointer to IOleObject is not freed.
      
            GetViewObject(lpView);
      								
    2. L'extraction d'une variable globale : la copie locale d'un pointeur d'interface rapporté à partir d'une copie existante du pointeur dans une variable globale doit être indépendamment référence compté car appelées fonctions peut détruire la copie dans le fichier global alors que la copie locale est encore active.
            void function()
            {
            // Get a pointer to IOleObject from a global variable.
            LPOLEOBJECT lpOleObject = glpObject;
      
            // This AddRef() is needed so that the interface
            // pointed to by the global variable, glpObject,
            // does not get released by a different part of
            // the applications code.
      
            lpOleObject->AddRef();
               .
               . // use lpOleObject;
               .
            lpOleObject->Release();
            }
      								
    3. Nouveaux pointeurs synthétisés de «avion léger»: une fonction qui synthétise un pointeur d'interface à l'aide des connaissances spéciales interne plutôt qu'obtention à partir d'une autre source doit faire une initiale AddRef() sur le pointeur qui vient d'être synthétisé. Important ces routines exemples de routines de création instance, les implémentations de IUnknown::QueryInterface et ainsi de suite.
            STDMETHDOIMP IUnknown::QueryInteface( REFIID iidInterface,
                                               LPVOID FAR *ppvObj)
            {
            *ppvObj = NULL;
            SCODE sc = E_NOINTERFACE;
      
            if (iidInterface == IUnknown)
                {
                *ppvObj = this;
      
                // This AddRef() is needed because a new pointer
                // was just created.
      
                AddRef();
               sc = S_OK;
                }
      
            return ResultFromScode(sc);
            }
      								
    4. Renvoi d'une copie d'un pointeur stocké en interne : une fois que le pointeur a été renvoyé, l'appelé n'a aucune idée comment sa durée de vie est liée à celle de la copie du pointeur stockée en interne. Par conséquent, l'appelé doit AddRef() le pointeur de copie avant de retourner à celui-ci.
            // m_lpOleObject is a private member variable of a C++ class.
            // GetOleObject is a member function to return access to this
            // pointer.
      
            void GetOleObject (LPVOID FAR *ppObject)
            {
                *ppObject = m_lpOleObject;
      
                // This AddRef() is needed due to this rule.
      
                m_lpOleObject->AddRef();
             }
      								
  2. Des connaissances spéciales de la part d'un morceau de code sur les relations entre le début et les terminaisons des durées de vie de deux ou plusieurs copies d'un pointeur d'interface peuvent permettre à AddRef()/Release() paires être omis.

    1. Paramètres aux fonctions : la copie d'un pointeur d'interface qui est passé comme paramètre réel à une fonction a une durée de vie qui est imbriquée dans la mesure où le pointeur utilisé pour initialiser la valeur. Par conséquent, le véritable paramètre pas nécessairement séparément référence compté.
            void function (LPOLEOBJECT lpOleObject)
            {
      
            // Can use lpOleObject in this function
            // without doing AddRef() and Release().
      
            }
      								
    2. Paramètres de sortie à partir de fonctions, y compris les valeurs de retour : pour définir le paramètre de sortie, la fonction elle-même par règle 1 doit disposer d'une copie stable le pointeur de l'interface. À la sortie, la responsabilité de libérer le pointeur est transférée à partir de l'appelé à l'appelant. Par conséquent, le paramètre de sortie ne doivent pas être référencé comptés.
            LPVIEWOBJECT lpView;
      
            HERROR hErr = lpOleObject->QueryInterface(IID_IViewObject,
                                                      (LPVOID FAR *)lpView);
      
            if (hErr = NOERROR)
                {
                // The QueryInterface succeeded. lpView does not have
                // to be AddRef()'d because it has already been done
                // by the QueryInterface method.
                }
      								
    3. Variables locales : une implémentation de la fonction a clairement omniscient connaissance des durées de vie de chaque variable pointeur alloué sur le frame de pile. Il peut par conséquent utiliser ces connaissances pour omettre les paires de AddRef()/Release() redondantes.
            void function()
            {
            LPOLEOBJECT lpTempObject;
               .
               .
               .
            lpTempObject = lpObject;
               .
               .  // lpTempObject can be used
               .  // without reference counting as long as
               .  // it is known that the lifetime of lpObject
               .  // outside of this function call.
               .
            }
      								
    4. Backpointers : certaines structures de données sont de la nature des contenant deux composants A et B, chacun avec un pointeur vers l'autre. Si la durée de vie d'un composant (A) est connue pour contenir la durée de vie de l'autre (B), puis le pointeur à partir du deuxième composant sauvegarder à la première (à partir de B à A) ne doivent pas être référence compté. Souvent, il est important pour préserver le comportement de libération approprié d'éviter le cycle serait créé dans le cas contraire.

Propriétés

Numéro d'article: 104138 - Dernière mise à jour: mercredi 3 décembre 2003 - Version: 3.1
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft OLE 2.0
  • Microsoft OLE 4.0 sur le système suivant
    • Microsoft Windows NT 4.0
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
    • the operating system: Microsoft Windows 2000
Mots-clés : 
kbmt kbprogramming KB104138 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 104138
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com