2009-02-25 8 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)); 
} 

En el código anterior quit se asigna en el montón y es necesario ya que es hijo de MyWidget¿Por qué Qt necesita asignar objetos secundarios en el Heap?

¿Por qué necesidades de Qt asignan los objetos secundarios en el montón?

+1

Si supongo que lo que quiere decir, su pregunta parece tonta, así que supongo que estoy equivocado en cuanto a su significado, por lo que debe alliterate. – mxcl

Respuesta

0

Creo que la idea aquí es que Qt tiene su propio recuento de referencia interna en la mayoría de los objetos y si pasa a su alrededor, usos de copia al escribir, etc.

Podría ser más específico en su pregunta?

+1

Los objetos compartidos implícitamente tienen una asignación de ** ** ** montón para los datos PIMPL, pero eso es un detalle de implementación. Un caso común en el que puede tener objetos contados de referencia solo de pila es pasar cualquier cosa implícitamente compartida a través de un evento enviado o una señal directamente conectada. Digamos, cuando pasa un 'QString' a una ranura usando una conexión directa. Ninguna de las instancias de cadena vive en el montón. El PIMPL vive en el montón, pero de nuevo, de eso no se trataba la pregunta. –

+0

Gracias por la comprensión. – ypnos

+0

Si están en el montón, y los objetos secundarios notifican a los padres de su eliminación, entonces usted tiene la opción de eliminarlos de manera bastante arbitraria. – spraff

-1

¿Qué otras opciones existen? De la pila? ¿Cómo sabría Qt cuándo asignar desde la pila y cuándo desde el montón? Las cosas asignadas de la pila desaparecerán tan pronto como regrese la función actual, por lo que la vida útil del objeto podría ser mucho más corta que el tiempo de uso. Imagine agregar un nodo a un árbol. El nodo se usará mucho después de que la función actual haya regresado. Esto llevaría al acceso a la memoria aleatoria, fallas de segmentación, volcados del núcleo, etc.

+1

Puede tenerlos como miembros de valor en otra clase de widget, para evitar la asignación de muchos objetos pequeños en todo el montón. – Macke

+0

¿Cómo sabría Qt lo que hizo cuando comienza a limpiar la memoria en el destructor? –

+2

Los objetos miembros se destruyen primero, por lo que se eliminan de su padre. Entonces el padre es destruido. No hay problema. (Esto funciona, así es como lo he hecho muchas veces. Solo tenga cuidado al usar boost :: shared_ptr y todo estará bien.) – Macke

2

Si entiendo lo que está preguntando correctamente, creo que en su mayoría se reduce a la tradición y el ejemplo, con un poco de dependencia del encabezado arrojado.

La alternativa, por supuesto, es declarar quit como una variable miembro de MyWidget. Si hace esto, entonces deberá incluir el archivo de encabezado para QPushButton donde se declara MyWidget, en lugar de en el archivo de implementación. El ejemplo que proporcionó también se basa en la relación de los padres de QObject para hacer un seguimiento de la memoria del botón y eliminarlo en la destrucción, por lo que no es necesario especificarlo como miembro de la clase.

Estoy bastante seguro de que podría cambiar a asignación de pila si realmente quisiera.

5

En su ejemplo, dejar de fumar no tiene que asignarse al montón.

Este código se compila y ejecuta bien:

struct MyWidget : QWidget 
{ 
    QPushButton quit; 

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

También funciona si agrega MyWidget como padre al botón de cerrar (que es más interesante, piensa). El botón se destruye antes de MyWidget y, por lo tanto, se desactiva antes de que MyWidget se destruya. – Macke

Cuestiones relacionadas