2009-10-30 11 views
14

yo estaba buscando en Qt ejemplo here:Qt: ¿"nuevo sin eliminar" causa pérdidas de memoria con controles?

y dentro del constructor, que tienen:

Window::Window() 
{ 
    editor = new QTextEdit(); // Memory leak? 
    QPushButton *sendButton = new QPushButton(tr("&Send message")); // Memory leak? 

    connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); 

    QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
    buttonLayout->addStretch(); 
    buttonLayout->addWidget(sendButton); 
    buttonLayout->addStretch(); 

    QVBoxLayout *layout = new QVBoxLayout(this); // Memory leak? 
    layout->addWidget(editor); 
    layout->addLayout(buttonLayout); 

    setWindowTitle(tr("Custom Type Sending")); 
} 

Esas líneas con comentarios

// Memory leak? 

no son las pérdidas de memoria?

Si es así, dado que la clase Window no tiene constructor, entonces debería hacer todas esas variables (el editor ya está) ¿Variables de miembros de Windows?

O ... ¿Qt internamente "borra" esas variables miembro cuando sale del alcance?

Respuesta

25

No, la función addWidget() mantendrá la propiedad del widget. A continuación, destruirá los widgets que posee.

Además se puede leer que here:

Al igual que con QObjects, QWidgets se pueden crear con objetos padres a indicar la propiedad, lo que garantiza que los objetos se eliminan cuando hay ya utilizado. Con los widgets, estas relaciones padre-hijo tienen un significado adicional de : cada widget hijo se muestra dentro del área de la pantalla ocupada por su widget padre. Esto significa que cuando elimina un widget de ventana , también se eliminan todos los widgets secundarios que contiene.

+0

+1 Estaba adivinando en mi respuesta eliminada :) – AraK

7

Si hay una excepción entre new y addWidget, entonces sí hay una pérdida de memoria. De lo contrario, el control principal toma posesión de la memoria.

QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
//make sure you don't throw here 
buttonLayout->addWidget(sendButton); 
5

Además de respuesta correcta de Klaim:

que almacenaría los punteros en un std::auto_ptr, por su parte los pases a sus padres.

std::auto_ptr<QHBoxLayout> buttonLayout(new QHBoxLayout()); 
// make things which could throw... 
layout->addLayout(buttonLayout.release()); 

De esta manera usted está seguro de no tener fugas.

+0

Incluso mejor que mi propia respuesta –

+0

¿No se borrará doblemente si haces esto? ¿Una vez por auto_ptr, otra vez por QObject? – James

+2

Reemplazar std :: auto_ptr por std :: unique_ptr ... – Klaim

0

No se eliminará doblemente debido a la llamada .release().

Nota std :: unique_ptr está reemplazando a std :: auto_ptr. Es de esperar que QT admita la semántica de movimiento, luego esa versión() sería en su lugar layout-> addLayout (std :: move (buttonLayout)) y sin la llamada para moverse, obtendría un error de compilación.

+1

es shared_ptr que reemplaza a auto_ptr, unique_ptr es solo para ptrs con alcance, no para compartir, dijo que es perfecto para este trabajo ya que no queremos compartirlo. –

Cuestiones relacionadas