2013-07-28 4 views
13

Ho il seguente codice:La relazione tra la dichiarazione di andata e distruttori

#include <iostream> 
using namespace std; 

class CForward; 

void func(CForward* frw) { delete frw; } 

class CForward 
{ 
public: 
    ~CForward() { cout << "Forward" << endl; } 
}; 

int main() 
{ 
    func(new CForward); 
    cin.get(); 
} 

ho eseguito il programma, ed è stampato nulla.

Perché?

in main, ho creato new CFoward e in func l'ho eliminato e l'ho chiamato distruttore.

Sembra che il distruttore non sia stato chiamato. Perché? E 'comunque collegato alla decelerazione diretta?

+0

'g ++' in realtà ti dice cosa sta succedendo quando compili questo codice. – fuenfundachtzig

+2

Almeno aumentare il livello di avviso sul compilatore. Questo dovrebbe sempre emettere una diagnostica "cancellazione del puntatore a tipo incompleto". –

+0

GCC è piuttosto utile: 'avviso: possibile problema rilevato in invocazione dell'operatore di cancellazione: [abilitato per impostazione predefinita] 'frw' ha tipo incompleto [abilitato per impostazione predefinita] forward dichiarazione di 'classe CForward' [abilitato per impostazione predefinita] nota: né il il distruttore e l'operatore specifico della classe delete verranno chiamati, anche se vengono dichiarati quando la classe è definita ». – juanchopanza

risposta

12

In effetti, la vostra dichiarazione anticipata introduce un tipo incompleto che viene successivamente definita con un distruttore non banale, e che non possono essere utilizzati in un'espressione di eliminazione:

Da n3337, paragrafo 5.3.5/5:

5 Se l'oggetto eliminato ha tipo classe incompleta al punto di delezione e la classe completa ha un distruttore non banale o una funzione deallocazione, il comportamento è unde definito.

+3

@ user1798362: se hai definito il distruttore di classe (piuttosto che usare solo quello generato dal compilatore), non è banale. In modo ricorsivo, se la tua classe ha membri con distruttori non banali, la tua classe ha un distruttore non banale. Tutti gli altri distruttori sono banali (in realtà non fanno nulla). –

1

Sì. Infatti nella funzione func, il compilatore non conosce il tipo completo di cForward. Quindi il descrittore è chiamato.

Se si inserisce la funzione dopo la lezione, funzionerà correttamente.