2010-02-22 26 views
5

estoy aprendiendo acerca de COM y la lectura de este código COM Release():Pregunta sobre el método

STDMETHODIMP_ (ULONG) ComCar::Release() 
{ 
    if(--m_refCount==0) delete this; 
    return m_refCount; 
} 

Mi pregunta es, si se elimina el == 0 m_refCount y el objeto, ¿cómo podría la variable miembro de instancia m_refCount ¿Todavía existe y se devolverá? Por favor, perdóneme si mi pregunta es tan ingenua porque soy totalmente novato en COM. Muchas gracias.

Un hilo relacionado es aquí: How could a member method delete the object?

+0

perdón por eso, gf. gracias por recordar. : D – smwikipedia

Respuesta

6

Su preocupación es válida, el recuento de ref se debe mover a una variable local antes de que se elimine el objeto.

STDMETHODIMP_ (ULONG) ComCar::Release() 
{ 
    ULONG refCount = --m_refCount; // not thread safe 
    if(refcount==0) delete this; 
    return refCount; 
} 

Pero incluso ese código sigue siendo incorrecto porque no es seguro para subprocesos.

debe usar un código como este en su lugar.

STDMETHODIMP_ (ULONG) ComCar::Release() 
    { 
    LONG cRefs = InterlockedDecrement((LONG*)&m_refCount); 
    if (0 == cRefs) delete this; 
    return (ULONG)max(cRefs, 0); 
    } 
+0

gracias John, pero tengo una sensación incómoda acerca de "borrar un objeto dentro del método miembro de ITS", ¿cómo podría ser posible? Si el objeto deja de existir, ¿cómo podría continuar la ejecución de su método miembro? Me pregunto si esto solo podría explicarse a través de alguna investigación sobre el diseño en memoria del objeto. – smwikipedia

+1

@smwikipedia: el código para las funciones existe independientemente de si la instancia de la clase existe o no. Las variables de pila existen hasta que salga de la función. Por lo tanto, no hay ningún problema con la función que continúa ejecutándose después de que la instancia que solíamos llamar desaparezca, siempre que no intentemos tocar ningún dato _instance_ después de la eliminación. aún puede tocar con seguridad estática y apilar variables y código. –

+0

Acabo de hacer un experimento. Escribí un método miembro con el cuerpo como "delet this", y la ejecución falló. Parecía haber algo de corrupción en la memoria. – smwikipedia

1

¿Seguro que la función está volviendo m_refCount?

Creo que acceder a las variables o métodos de miembro después de que un objeto ha sido eliminado no está definido de acuerdo con el estándar, y nunca se puede hacer esto de manera confiable.

La única forma en que creo que esto podría funcionar es si el método Release() crea una variable local en la pila con una copia del recuento de referencias, y esta se devuelve a través de return value optimization.