2010-07-14 15 views
24

C'è qualche differenza tra un distruttore protetto e privato in C++? Se un distruttore delle classi di base è privato, immagino che venga ancora chiamato quando si elimina l'oggetto classe derivata.Protetto contro il private Destructor

+4

Avrai alcuni problemi derivanti dalla classe con distruttore privato =) – SadSido

+0

Duplicato per http://stackoverflow.com/questions/631783/questo-è-il-del-uso-di-having-distruttore-come-privato ? – SadSido

+1

Domanda simile qui: http://stackoverflow.com/questions/224966/private-and-protected-members-c – Jordan

risposta

12

Tratto da here:

Se il costruttore/distruttore viene dichiarata come privata, allora la classe non può essere istanziato.

Questo è vero, tuttavia può essere istanziato da un altro metodo nella classe. Allo stesso modo, se il distruttore è private, l'oggetto può essere eliminato anche all'interno della classe. Inoltre, impedisce l'ereditarietà della classe (o almeno impedisce che la classe ereditata venga istanziata/distrutta).

+4

public class A {private A() {} public A getA() {return new A(); }} Non esattamente vero. –

+2

Non è vero. L'oggetto con distruttore privato * può * essere istanziato, (su una pila all'interno di una funzione amico, per esempio). – SadSido

+2

Right non può essere allocato allo stack ma può essere assegnato all'heap e anche dalle funzioni friend ... –

22

Se il distruttore della classe base è private o protected, non è possibile chiamare delete tramite il puntatore della classe base.

Utilizzare un distruttore protetto per impedire la distruzione di un oggetto derivato tramite un puntatore di classe base. Limita l'accesso al destuctor alle classi derivate. E impedisce gli oggetti automatici (stack) di classe base.

In effetti è usato per consentire a qualsiasi altra uso polimorfica di derivati ​​ classi tramite puntatori alla base, ma non consentire agli utenti di eliminare utilizzando tale puntatore . Esempio: - Classi di base/interfacce astratte.

Ma un protected, non-virtual distruttore sembra essere un bug in attesa di accadere. Supponendo che tu non fornisca una funzione destroy(), devi eventualmente rendere pubblico il dtor. Appena lo fai, non hai più alcun controllo sulla classe e corri il rischio di una cancellazione polimorfica con un attore non virtuale, se qualcuno si allontana ulteriormente dalla tua classe.

6

Il seguente pezzo di codice comporterà l'errore del compilatore (VC2010): C2248: 'base :: ~ base': non può accedere membro privato dichiarato nella classe di 'base'

class base 
{ 
    ~base(){} 
}; 

class derived : public base 
{ 
}; 

int main() 
{ 
    derived* d = new derived; 

    delete d; 
} 

Tuttavia, se si cambia il distruttore di base da proteggere, tutto funziona correttamente.

+0

Ma anche se lo hai cambiato in 'protected', non puoi distruggere oggetti attraverso un puntatore di classe base. (In tal caso dovrebbe anche essere 'virtuale', BTW.) Che in qualche modo sconfigge molti degli scopi della derivazione ... – sbi

6

La risposta è che la tua ipotesi è sbagliata. Il distruttore della classe base non può essere chiamato quando è privato.

+0

Quindi, come viene distrutta la mia classe? – doron

+0

@ deus-ex-machina399: non può. Quindi non puoi derivarne. E non puoi creare oggetti automatici di esso. E gli oggetti dinamici non possono mai essere cancellati (a meno che tu non fornisca una funzione membro che lo fa). – sbi

Problemi correlati