Regras de contagem de referência

Traduções de Artigos Traduções de Artigos
Artigo: 104138 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

No modelo de objecto de componente, duração de uma interface é controlada através da contagem de referência. A contagem de referência para uma interface é manipulada através de funções de membro AddRef() e Release() herdadas de IUnknown. O membro AddRef() incrementa a contagem de referência de uma interface e diminui o método Release()-lo. Depois de contagem de referência de uma interface vai para zero, já não existem quaisquer apontadores válidos para essa interface. Se a contagem de referência em todas as interfaces de um objecto for zero, em seguida, o objecto pode ser libertado porque já não existem quaisquer indicações para o objecto.

Mais Informação

Regras de contagem de referência

A lista que se segue é uma cópia da referência contagem regras (retiradas de páginas 83 e 84 da especificação de OLE 2.0) que têm de ser cumpridas. Exemplos de código pequeno foram adicionados neste artigo para ajudar a clarificar as regras.

  1. Cada nova cópia de um apontador de interface tem de ser AddRef iria () e cada destruição de um apontador de interface tem de ser Release () iria excepto onde esta regra for accionada permite explicitamente caso contrário.

    1. parâmetros de saída para funções : O emissor tem AddRef() o parâmetro real, porque irá ser Release () iria pelo destinatário da chamada quando o out-value é armazenado por cima.
            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. a obtenção de uma variável global : A cópia local de um apontador de interface obtido a partir da cópia existente do ponteiro numa variável global tem de ser independentemente referência contada porque chamado funções poderá destruir a cópia no global enquanto a cópia local estiver ainda activa.
            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. novos ponteiros síntese de "fino ar" : função que synthesizes um apontador de interface utilizando conhecimento especial interno em vez de obtê-la de alguns outra origem tem de efectuar um AddRef() inicial no ponteiro recentemente sintetizado. Importante estas rotinas exemplos de rotinas de criação de instância, implementações do IUnknown::QueryInterface e assim sucessivamente.
            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. devolver uma cópia de um ponteiro armazenada internamente : uma vez que o ponteiro foi devolvido, o destinatário da chamada tem não faz ideia como se relaciona sua vida útil com que a cópia armazenada internamente do ponteiro. Assim, o destinatário da chamada tem AddRef() copiar o ponteiro antes de regressar à mesma.
            // 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. Conhecimento especial parte de um segmento de código sobre as relações de início e terminações de durações de duas ou mais cópias de um apontador de interface pode permitir que AddRef()/Release() pares ser omitido.

    1. em parâmetros para funções : A cópia de um apontador de interface passado como parâmetro de real a uma função com uma duração está aninhada em que o ponteiro utilizado para inicializar o valor. Por conseguinte, o parâmetro real não precisa ser separadamente referência contada.
            void function (LPOLEOBJECT lpOleObject)
            {
      
            // Can use lpOleObject in this function
            // without doing AddRef() and Release().
      
            }
      								
    2. parâmetros de saída de funções, incluindo valores de retorno : para definir o parâmetro de saída, a própria função por Rule 1 tem de ter uma cópia estável do apontador de interface. Ao sair, a responsabilidade de libertar o ponteiro é transferida do destinatário da chamada para o autor da chamada. Deste modo, o parâmetro out não necessita de ser referenciado contados.
            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. as variáveis locais : A implementação de função tem claramente omniscient conhecimento de durações de cada uma das variáveis ponteiro atribuídas da moldura de pilha. Assim pode utilizar este conhecimento para omitir pares AddRef()/Release() redundantes.
            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 : algumas estruturas de dados são de natureza com dois componentes, A e B, cada uma com um ponteiro para o outro. Se a duração de um componente (A) é conhecida para incluir a validade de outros (B), o ponteiro do segundo componente novamente para o primeiro (do B a) tem de não ser referência contada. Muitas vezes, evitar o ciclo caso contrário, deverá ser criado é importante manter o comportamento de libertar adequado.

Propriedades

Artigo: 104138 - Última revisão: 3 de dezembro de 2003 - Revisão: 3.1
A informação contida neste artigo aplica-se a:
  • Microsoft OLE 2.0
  • Microsoft OLE 4.0 nas seguintes plataformas
    • 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
Palavras-chave: 
kbmt kbprogramming KB104138 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 104138

Submeter comentários

 

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