2009-02-25 15 views
6
class MyWidget : public QWidget { public: 
    MyWidget(QWidget *parent=0, const char *name=0); }; 


MyWidget::MyWidget(QWidget *parent, const char *name) 
     : QWidget(parent, name) { 
    QPushButton *quit = new QPushButton("Quit", this, "quit"); 
    quit->setGeometry(62, 40, 75, 30); 
    quit->setFont(QFont("Times", 18, QFont::Bold)); 
} 

Nel codice precedente quit viene allocato in mucchio ed è necessario perché è figlio di myWidgetPerché Qt ha bisogno di allocare oggetti figlio nell'heap?

Perché esigenze Qt allocano di oggetti secondari nel mucchio?

+1

Se Credo che quello che vuoi dire, la sua domanda sembra stupida, quindi presumo mi sbaglio come al significato, così si dovrebbe alliterate. – mxcl

risposta

0

Penso che l'idea qui è che Qt ha il proprio conteggio di riferimento interno sulla maggior parte degli oggetti e se si passa in giro, si avvale di copy-on-write ecc

Potrebbe essere più specifico nella tua domanda?

+1

Gli oggetti implicitamente condivisi fanno ** allocazione heap ** interna per i dati PIMPL, ma questo è un dettaglio di implementazione. Un caso comune in cui è possibile avere oggetti conteggio di riferimento solo stack è il passaggio di qualsiasi cosa implicitamente condivisa tramite un evento inviato o un segnale direttamente connesso. Dite, quando passate un 'QString' ad uno slot usando una connessione diretta. Nessuna delle istanze di stringa vive nell'heap. PIMPL vive sullo heap, ma ancora, non è di questo che si trattava. –

+0

Grazie per l'intuizione. – ypnos

+0

Se sono nell'heap e gli oggetti figlio notificano ai genitori la loro cancellazione, allora avete la possibilità di cancellarli in modo abbastanza arbitrario. – spraff

-1

Quali altre opzioni ci sono? Dalla pila? Come fa Qt a sapere quando allocare dallo stack e quando dall'heap? Le cose allocate dallo stack scompariranno non appena verrà ripristinata la funzione corrente, quindi la durata dell'oggetto potrebbe essere molto più breve del tempo di utilizzo. Immagina di aggiungere un nodo ad un albero. Il nodo verrà utilizzato molto tempo dopo che è stata restituita la funzione corrente. Ciò porterebbe all'accesso alla memoria casuale, agli errori di segmentazione, ai core dump, ecc.

+1

Si potrebbero avere come membri valore in un'altra classe widget, per evitare di allocare molti piccoli oggetti in tutto l'heap. – Macke

+0

Come fa Qt a sapere cosa hai fatto quando inizia a ripulire la memoria nel distruttore? –

+2

Gli oggetti membri vengono prima distrutti, quindi si separano dai loro genitori. Quindi il genitore viene distrutto. Nessun problema. (Funziona, è come ho fatto molte volte. Stai attento a usare boost :: shared_ptr e tutto andrà bene.) – Macke

2

Se capisco cosa stai chiedendo correttamente, penso che si riduce principalmente alla tradizione e all'esempio, con un po 'di dipendenza dall'intestazione gettato.

L'alternativa, naturalmente, è dichiarare quit come variabile membro di MyWidget. Se si esegue questa operazione, è necessario includere il file di intestazione per QPushButton dove viene dichiarato MyWidget anziché nel file di implementazione. L'esempio che hai fornito si basa anche sulla relazione genitore di QObject s per tenere traccia della memoria per il pulsante ed eliminarlo in caso di distruzione, quindi non è necessario specificarlo come membro nella classe.

Sono abbastanza sicuro che si potrebbe cambiare l'allocazione dello stack, se proprio si voleva.

5

Nel proprio esempio, non è necessario allocare heap.

Questo codice compila ed esegue bene:

struct MyWidget : QWidget 
{ 
    QPushButton quit; 

    MyWidget() 
    { 
     quit.setGeometry(62, 40, 75, 30); 
     quit.setFont(QFont("Times", 18, QFont::Bold)); 
    } 
}; 
+4

Funziona anche se aggiungi MyWidget come padre al pulsante di uscita (che è più interessante, I pensa). Il pulsante viene distrutto prima di MyWidget e quindi viene de-parentato prima che MyWidget venga distrutto. – Macke

Problemi correlati