Implementación del recuento de referencias

El recuento de referencias requiere trabajo en la parte del implementador de una clase y los clientes que usan objetos de esa clase. Al implementar una clase, debe implementar los métodos AddRef y Release como parte de la interfaz IUnknown . Estos dos métodos tienen las siguientes implementaciones sencillas:

  • AddRef incrementa el recuento de referencias internas del objeto.
  • Liberar primero disminuye el recuento de referencias internas del objeto y, a continuación, comprueba si el recuento de referencias ha caído en cero. Si lo tiene, significa que nadie usa el objeto ya, por lo que la función Release desasigna el objeto.

Un enfoque de implementación común para la mayoría de los objetos es tener solo una implementación de estos métodos (junto con QueryInterface), que se comparte entre todas las interfaces y, por lo tanto, un recuento de referencias que se aplica a todo el objeto. Sin embargo, desde la perspectiva de un cliente, el recuento de referencias es estrictamente y claramente una noción de puntero por interfaz y, por lo tanto, los objetos que aprovechan esta funcionalidad construyendo, destruyendo, cargando o descargando partes de su funcionalidad en función de los punteros de interfaz existentes actualmente se pueden implementar. Se denominan interfaces de desmontaje coloquialmente.

Cada vez que un cliente llama a un método (o función de API), como QueryInterface, que devuelve un nuevo puntero de interfaz, el método al que se llama es responsable de incrementar el recuento de referencias a través del puntero devuelto. Por ejemplo, cuando un cliente crea un objeto por primera vez, recibe un puntero de interfaz a un objeto que, desde el punto de vista del cliente, tiene un recuento de referencias de uno. Si el cliente llama a AddRef en el puntero de interfaz, el recuento de referencias se convierte en dos. El cliente debe llamar a Release dos veces en el puntero de interfaz para quitar todas sus referencias al objeto .

Un ejemplo de cómo los recuentos de referencias son estrictamente por puntero de interfaz cuando un cliente llama a QueryInterface en el primer puntero para una nueva interfaz o la misma interfaz. En cualquiera de estos casos, se requiere que el cliente llame a Release una vez para cada puntero. COM no requiere que un objeto devuelva el mismo puntero cuando se le solicite la misma interfaz varias veces. (La única excepción a esto es una consulta a IUnknown, que identifica un objeto a COM). Esto permite que la implementación de objetos administre los recursos de forma eficaz.

La seguridad de subprocesos también es un problema importante en la implementación de AddRef y Release. Para obtener más información, vea Procesos, subprocesos y apartamentos.

Administración de la duración del objeto mediante el recuento de referencias