Regras de contagem de referência

Traduções deste artigo Traduções deste artigo
ID do artigo: 104138 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

No modelo de objeto componente, tempo de vida da interface é controlado por meio de contagem de referência. A contagem de referência para uma interface é manipulada através das funções de membro AddRef() e Release() herdadas de IUnknown. O membro AddRef() incrementa a contagem de referência da interface e o Release() método diminui-la. Depois de contagem de referência da interface vai para zero, não há qualquer ponteiros válidos para essa interface. Se a contagem de referência em todas as interfaces de um objeto for zero, em seguida, o objeto pode ser liberado porque não há qualquer ponteiros para o objeto.

Mais Informações

Regras de contagem de referência

A lista a seguir é uma cópia da referência da contagem de regras (extraídas páginas 83 e 84 da especificação do OLE 2.0) que devem ser seguidas. Exemplos de código pequeno foram adicionados neste artigo para ajudar a esclarecer as regras.

  1. Cada nova cópia de um ponteiro de interface deve ser AddRef () ' d, e cada destruição de um ponteiro de interface deve ser versão () seria exceto onde regras subseqüentes permitem explicitamente caso contrário.

    1. parâmetros de saída para funções : O chamador deve AddRef() o parâmetro real, porque será versão () seria pelo receptor quando o out-value é armazenada em cima dele.
            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. buscando uma variável global : A cópia local de um ponteiro de interface obtido de uma cópia existente do ponteiro em uma variável global deve ser independentemente referência contabilizada porque chamado funções pode destruir a cópia no global enquanto a cópia local está ainda ativa.
            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 sintetizados fora do "ar" : uma função synthesizes um ponteiro de interface usando conhecimento interno especial em vez de obtenção de outra origem deve fazer um AddRef() inicial no ponteiro recém-sintetizado. Importante como rotinas exemplos de rotinas de criação de instância, implementações de IUnknown::QueryInterface e assim por diante.
            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. Retornando uma cópia de um ponteiro armazenada internamente : depois que o ponteiro foi retornado, o chamador não tem idéia como se relaciona sua vida com que a cópia armazenada internamente o ponteiro. Portanto, o chamador deve AddRef() o ponteiro copiar antes de retornar a ele.
            // 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 na parte de um trecho de código sobre as relações entre o início e terminações das vidas úteis de dois ou mais cópias de um ponteiro de interface pode permitir que AddRef()/Release() pares para ser omitido.

    1. em parâmetros para funções : A cópia de um ponteiro de interface que é passado como um parâmetro real para uma função tem uma vida útil que está aninhada em que o ponteiro usado para inicializar o valor. Portanto, o parâmetro real não precisa ser separadamente referência contabilizada.
            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 : definir o parâmetro de saída, a própria função por regra 1 deve ter uma cópia estável do ponteiro de interface. Na saída, a responsabilidade de liberar o ponteiro é transferida do receptor para o chamador. Portanto, o parâmetro de saída não precisa 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. variáveis locais : A implementação de função claramente tem conhecimento omniscient das vidas úteis de cada um das variáveis de ponteiro alocadas no quadro de pilha. Ele, portanto, pode usar esse 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 da natureza do que contém dois componentes, A e B, cada um com um ponteiro para o outro. Se o tempo de vida de um componente (A) é conhecido por conter o tempo de vida da outros (B), o ponteiro do segundo componente de volta para o primeiro (de B para A) precisa não referência contabilizada. Com freqüência, evitar o ciclo que seria criado caso contrário, é importante manter o comportamento de liberar apropriado.

Propriedades

ID do artigo: 104138 - Última revisão: quarta-feira, 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 traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes 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