2012-11-16 10 views
5

Ive visto sintassi GUI Qt come il seguente tutto il luogo:verrà distrutto() essere emesso se il costruttore di una classe derivata da QObject getta?

myDialog::myDialog(QWidget *parent, Qt::WFlags flags):QDialog(parent, flags) 
{ 
    QPushButton *button = new QPushButton("&Download", this); 
    QVBoxLayout *layout = new QVBoxLayout(this); 
    //something that can throw here 
    layout ->addWidget(button); 
    setLayout(layout); 
} 

mi sono sempre chiesto se questo può fuoriuscire in caso di un'eccezione perché il "questo" sto dando come un genitore a il pulsante e il layout non sono completamente costruiti in modo che non possano distruggere i suoi figli.

L'ho provato in MSVC2010 Qt4.8.3 e sembra che non appena la classe QObject di base sia completamente creata (cosa che viene fatta prima ovviamente) è ok passare "questo" ad altri oggetti nel costruttore, saranno distrutti correttamente.

Non ho trovato il punto nei documenti Qt a garantirlo, ma qualcuno può indicarmi di farlo quindi ho la certezza che questo non cambierà in futuro?

risposta

2

Credo sia il C++ standard a garantire che sia un base constructor is executed prior to derived constructors, anche se non posso citare capitolo e versetto dallo standard. Detto questo, c'è una garanzia che uno QObject's destructor distruggerà sempre qualsiasi figlio di quel QObject.

La convenzione Qt è che un oggetto QO il cui puntatore viene passato a un costruttore QObject o QWidget diventerà il genitore dell'oggetto appena costruito. Pertanto, quando si passa il numero this a button, il numero button diventa un figlio di myDialog. Poiché la porzione QObject di myDialog sarà già stata costruita in quel momento, credo che si possa fare affidamento su tale funzionalità in modo sicuro.

EDIT: Vorrei aggiungere che, nell'esempio di cui sopra, anche se button inizia come un bambino di myDialog causa al costruttore, si ottiene reparented quando aggiunto a layout e diventa un grand-figlio di myDialog, che dovrebbe essere ancora cancellato dal suo distruttore QObject.

+0

Il distruttore di QObject non verrà chiamato se il costruttore myDialog genera. Ci sarà una perdita con il codice originale. –

+3

Non penso sia corretto. Il distruttore della classe base dovrebbe ancora essere chiamato. http://stackoverflow.com/questions/3759270/will-the-destructor-of-the-base-class-called-if-an-object-throws-an-exception-in – Phlucious

+0

hai di nuovo ragione. Grazie per la segnalazione. –

Problemi correlati