Domanda

    

Questa domanda ha già una risposta qui:

    
            
  •              è Elimina questo permesso?                                      10 risposte                          
  •     
    

Nel mio test di base iniziale è perfettamente sicuro per farlo. Tuttavia, mi ha colpito il fatto che il tentativo di manipolare this tardi in una funzione che deletes this potrebbe essere un errore di runtime. E 'vero, ed è normalmente sicuro delete this? o ci sono solo alcuni casi in cui è sicuro?

È stato utile?

Soluzione

delete this è legale e fa quello che ci si aspetta: chiama il distruttore di vostra classe e libera la memoria sottostante. Dopo i rendimenti delete this, il vostro valore del puntatore this non il cambiamento, quindi è ora un puntatore penzoloni che dovrebbe non essere dereferenziato. Che include dereferenziazione implicita utilizzando variabili membro della classe.

Si trova solitamente in classi di riferimento conteggiata che, quando l'arbitro conteggio viene decrementato a 0, il DecrementRefCount() / Release() / qualunque funzione membro chiamate delete this.

delete this è in genere considerato forma molto male per molte ragioni. E 'facile accedere accidentalmente variabili membro dopo delete this. codice chiamante potrebbe non realizzare il vostro oggetto ha autodistruzione.

Inoltre, delete this è un "codice odore" che il codice potrebbe non avere una strategia simmetrica per la proprietà oggetto (che assegna e chi cancella). Un oggetto non poteva sé allocato con new, così chiamata delete this significa che la classe A è l'allocazione di un oggetto, ma di classe B è successivamente liberandola [auto].

Altri suggerimenti

E 'sicuro per eliminare "questo" fintanto che è in sostanza l'ultima operazione nel metodo. Infatti diverse API di livello professionale farlo (vedi implementazione CComObject di ATL per un esempio).

L'unico pericolo sta tentando di accedere ad altri dati dei membri dopo aver chiamato "cancella questo". Questo è certamente pericoloso.

Cancella questo è perfettamente legale come altri hanno già detto. E 'rischioso per un motivo che non è stato ancora citato - si stanno assumendo che l'oggetto è stato allocato sul mucchio. Questo può essere difficile da garantire, anche se nel caso di implementazioni di conteggio di riferimento non è generalmente un problema.

, ma non lo fate nel distruttore!

Come già detto da altri, eliminare questo è un idioma valido, ma per essere sicuri è necessario assicurarsi che l'oggetto non viene mai istanziato in pila.

Un modo per farlo è quello di fare sia il costruttore e il distruttore privato e far rispettare la creazione di oggetti tramite una funzione di classe factory che crea l'oggetto sul mucchio e restituisce un puntatore ad esso. La fabbrica di classe può essere una funzione membro statica o una funzione amico. Cleanup può essere fatto attraverso un metodo Delete () sull'oggetto che non il "cancella questo". COM oggetti fondamentalmente funziona in questo modo, tranne che in aggiunta sono riferimento conteggiato con lo "cancellare questo" si verifica quando il conteggio di riferimento viene decrementato a zero.

Sì. Dovrebbe essere perfettamente bene. "Questo" è solo un puntatore. Qualsiasi puntatore farà per eliminazione. Le informazioni su come eliminare un oggetto è contenuto nei registri heap. Questo è il modo IUnknown :: Release () è di solito implementato in oggetti COM.

cancellare questo può causare un problema quando si hanno sottoclassi dell'oggetto che si sta eliminando. Ricordate che inizi la costruzione dall'alto verso il basso e la cancellazione inizia dal basso verso l'alto. Quindi, se cancellare questo è nel mezzo della gerarchia che, fondamentalmente perso tutti gli oggetti di sotto di questa particolare classe.

cancella questa è molto utile quando si implementa un oggetto di riferimento contati, di cui un esempio sono le classi COM.

Leggi per una discussione simile. La vostra comprensione è proprio di che funziona, è necessario, e può essere pericoloso, in quanto non è possibile accedere a questo in seguito.

Si legale
Sicuro: No

Se si eredita da una classe base e ha dato cancellare questo nella funzione classe base, utilizzando il puntatore classe derivata causerà un crash. Per esempio:

class Base
{

    virtual void Release()
    {
        delete this;
    }

}

class Derived : public Base
{

    void Foo()
    {
        ...
    }

}

main()
{

    Base *ptrDerived = new Derived();
    ptrDerived->release();
    ptrDerived->Foo() //Crash

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top