Condividi tramite


Implementazione del conteggio dei riferimenti

Il conteggio dei riferimenti richiede il lavoro da parte dell'implementatore di una classe e dei client che usano oggetti di tale classe. Quando si implementa una classe, è necessario implementare i metodi AddRef e Release come parte dell'interfaccia IUnknown. Questi due metodi hanno le implementazioni semplici seguenti:

  • AddRef incrementa il conteggio dei riferimenti interni dell'oggetto.
  • Rilascia prima decrementa il conteggio dei riferimenti interni dell'oggetto e quindi verifica se il conteggio dei riferimenti è sceso a zero. In caso affermativo, ciò significa che nessuno usa più l'oggetto, quindi la funzione Release dealloca l'oggetto.

Un approccio di implementazione comune per la maggior parte degli oggetti consiste nell'avere una sola implementazione di questi metodi (insieme a QueryInterface), che viene condivisa tra tutte le interfacce e quindi un conteggio dei riferimenti applicabile all'intero oggetto. Tuttavia, dal punto di vista di un client, il conteggio dei riferimenti è rigorosamente e chiaramente una nozione di puntatore per interfaccia e pertanto oggetti che sfruttano questa funzionalità creando, distruggendo, caricando o scaricando parti delle relative funzionalità in base ai puntatori di interfaccia attualmente esistenti possono essere implementati. Si tratta di interfacce colloquialmente chiamate tear-off.

Ogni volta che un client chiama un metodo (o una funzione API), ad esempio QueryInterface, che restituisce un nuovo puntatore di interfaccia, il metodo chiamato è responsabile dell'incremento del conteggio dei riferimenti tramite il puntatore restituito. Ad esempio, quando un client crea un oggetto, riceve un puntatore di interfaccia a un oggetto che, dal punto di vista del client, ha un conteggio dei riferimenti di uno. Se il client chiama quindi AddRef sul puntatore all'interfaccia, il conteggio dei riferimenti diventa due. Il client deve chiamare Release due volte sul puntatore dell'interfaccia per eliminare tutti i relativi riferimenti all'oggetto .

Un esempio di come i conteggi dei riferimenti siano rigorosamente per ogni puntatore a interfaccia si verifica quando un client chiama QueryInterface sul primo puntatore per una nuova interfaccia o per la stessa interfaccia. In uno di questi casi, il client deve chiamare Release una volta per ogni puntatore. COM non richiede che un oggetto restituisca lo stesso puntatore quando viene richiesta più volte la stessa interfaccia. (L'unica eccezione a questa è una query a IUnknown, che identifica un oggetto in COM.) Ciò consente all'implementazione dell'oggetto di gestire le risorse in modo efficiente.

Thread-safety è anche un problema importante nell'implementazione di AddRef e Release. Per altre informazioni, vedere Processi, thread e appartamenti.

Gestione delle durate degli oggetti tramite il conteggio dei riferimenti