Implementera referensräkning

Referensräkning kräver arbete från både implementorn för en klass och klienterna som använder objekt i den klassen. När du implementerar en klass måste du implementera metoderna AddRef och Release som en del av gränssnittet IUnknown. Dessa två metoder har följande enkla implementeringar:

  • AddRef ökar objektets interna referensantal.
  • Release minskar först objektets interna referensantal och kontrollerar sedan om referensantalet har sjunkit till noll. Om den har det innebär det att ingen använder objektet längre, så funktionen Release frigör objektet.

En vanlig implementeringsmetod för de flesta objekt är att bara ha en implementering av dessa metoder (tillsammans med QueryInterface), som delas mellan alla gränssnitt och därför ett referensantal som gäller för hela objektet. Men från en klients perspektiv är referensräkning strikt och tydligt ett begrepp per gränssnittspekare, och därför kan objekt som drar nytta av den här funktionen genom att dynamiskt konstruera, förstöra, läsa in eller ta bort delar av deras funktioner baserat på de aktuella befintliga gränssnittspekarna implementeras. Dessa kallas informellt avrivningsgränssnitt.

När en klient anropar en metod (eller API-funktion), till exempel QueryInterface, som returnerar en ny gränssnittspekare, ansvarar metoden som anropas för att öka referensantalet via den returnerade pekaren. När en klient till exempel först skapar ett objekt tar den emot en gränssnittspekare till ett objekt som från klientens synvinkel har ett referensantal på ett. Om klienten sedan anropar AddRef- på gränssnittspekaren blir referensantalet två. Klienten måste anropa Release två gånger på gränssnittspekaren för att släppa alla dess referenser till objektet.

Ett exempel på hur referensantalet är strikt per gränssnittspekare inträffar när en klient anropar QueryInterface på den första pekaren för antingen ett nytt gränssnitt eller samma gränssnitt. I något av dessa fall måste klienten anropa Release en gång för varje pekare. COM kräver inte att ett objekt returnerar samma pekare när det efterfrågas samma gränssnitt flera gånger. (Det enda undantaget är en fråga som IUnknown, som identifierar ett objekt för COM.) På så sätt kan objektimplementeringen hantera resurser effektivt.

Trådsäkerhet är också ett viktigt problem vid implementering av AddRef och Release. Mer information finns i Processer, Trådar och Lägenheter.

hantera objektlivslängder via referensräkning