2010-02-22 8 views
5

ich über COM am Lernen und Lesen über diesen Code:Frage zum COM Release() Methode

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

Meine Frage ist, wenn der m_refcount == 0 und das Objekt gelöscht wird, wie könnte die Instanz Membervariable m_refCount noch vorhanden und zurückgegeben werden? Bitte vergib mir, wenn meine Frage so naiv ist, weil ich ein total Neuling auf COM bin. Danke vielmals.

Ein verwandter Thread hier: How could a member method delete the object?

+0

Entschuldigung, gf. Danke für das Erinnern. : D – smwikipedia

Antwort

6

Ihr Anliegen ist gültig, die ref count sollte in eine lokale Variable verschoben werden, bevor das Objekt gelöscht wird.

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

Aber auch dieser Code ist immer noch falsch, weil er nicht threadsicher ist.

sollten Sie stattdessen Code wie dieser verwenden.

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

danke John, aber ich habe ein unheimliches Gefühl über "Löschen eines Objekts innerhalb der ITS-Member-Methode", wie könnte das möglich sein? Wenn das Objekt nicht mehr existiert, wie könnte die Ausführung seiner Methode fortgesetzt werden? Ich frage mich, ob dies nur durch einige Untersuchungen über das In-Memory-Layout des Objekts erklärt werden könnte? – smwikipedia

+1

@smwikipedia: Der Code für die Funktionen existiert unabhängig davon, ob die Instanz der Klasse existiert oder nicht. Stack-Variablen existieren, bis Sie die Funktion verlassen. Es gibt also kein Problem damit, dass die Funktion weiterhin ausgeführt wird, nachdem die Instanz, mit der wir sie aufgerufen haben, verschwindet, solange wir nicht versuchen, nach dem Löschen irgendwelche _instance_-Daten zu berühren. Sie können immer noch sicher Statik und Stapel Variablen und Code berühren. –

+0

Ich habe gerade ein Experiment gemacht. Ich schrieb eine Member-Methode mit dem Körper wie "Delet this", und die Ausführung fehlgeschlagen. Es schien eine gewisse Speicherkorruption zu geben. – smwikipedia

1

Sind Sie sicher, dass die Funktion m_refCount zurückkehrt?

Ich glaube, dass der Zugriff auf Member Variablen oder Methoden nach dem Löschen eines Objekts ist nicht definiert nach dem Standard, und Sie können nie zuverlässig dies tun.

Die einzige Möglichkeit, die ich denke, könnte funktionieren, wenn die Release() Methode eine lokale Variable auf dem Stapel mit einer Kopie der Referenzzahl erstellt, und dies über return value optimization zurückgegeben wird.