PDA

View Full Version : what time should I delete the resource



stereoMatching
20th January 2011, 19:19
According to the code come from
C++ GUI Programming with Qt4, sec edition

As the example of Ch2


#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
Q_OBJECT

public:
FindDialog(QWidget *parent = 0);

signals:
void findNext(const QString &str, Qt::CaseSensitivity cs);
void findPrevious(const QString &str, Qt::CaseSensitivity cs);

private slots:
void findClicked();
void enableFindButton(const QString &text);

private:
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
};

#endif





#include <QtGui>

#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent)
: QDialog(parent)
{
label = new QLabel(tr("Find &what:"));
lineEdit = new QLineEdit;
label->setBuddy(lineEdit);

caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));

findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true);
findButton->setEnabled(false);

closeButton = new QPushButton(tr("Close"));

connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindButton(const QString &)));
connect(findButton, SIGNAL(clicked()),
this, SLOT(findClicked()));
connect(closeButton, SIGNAL(clicked()),
this, SLOT(close()));

QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);

QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);

QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);

setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs =
caseCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive;
if (backwardCheckBox->isChecked()) {
emit findPrevious(text, cs);
} else {
emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}





#include <QApplication>

#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}



I do not see the code release any resource of the class
and I haven't see they use anything like smart pointer
the book said


Qt automatically deletes child objects when the parent is destroyed, and
the child widgets and layouts are all descendants of the FindDialog


did that mean if all of the dynamic memory are allocated within class
Qt would release the resource for us?
Could I just use smart pointer like
std::unique_ptr for it?
for this example, the
QHBoxLayout and
QVBoxLayout
should be declared as private members if I want to use
std::unique_ptr

I am very worry about the coding style like that
it do not "seems like" they release the memory they claim for
I don't want to fall into the trap of memory allocation in the future
Thanks a lot

ps : the class would release the resource because we declare the
Q_OBJECT?
whatever, this makes me feel unsafe

Zlatomir
20th January 2011, 19:40
Let's take the Hello World example and explain how to deal with allocating memory on heap for the parent:

#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QWidget *w = new QWidget(0);

QVBoxLayout *l = new QVBoxLayout(w); //has a parent
QLabel *lbl = new QLabel("Hello World"); //no parent at construction, but it will get one later
QPushButton *btn = new QPushButton("Close"); //no parent at construction, but it will get one later
QObject::connect(btn, SIGNAL(clicked()), qApp, SLOT(quit()));

l->addWidget(lbl); //will reparent the label, w will be the parent
l->addWidget(btn); //will reparent the button, w will be the parent

w->show();

int ret_val = app.exec();

delete w; //delete the parent, this will trigger the deletion of it's children

return ret_val;
}
So yes, this code will leak:

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}
You can allocate memory on the stack (here in main.cpp) but in any other parts you will need to be careful about the lifetime of your objects (it's a pretty common mistake to allocate on the stack and the objects get deleted before you try to use them)

wysota
20th January 2011, 19:41
A very simplified explanation of what is going on:

class QObject {
public:
QObject(QObject *parent = 0) : m_parent(0){
setParent(parent);
}
void setParent(QObject *parent) {
if(m_parent) m_parent->m_children.removeOne(this);
m_parent = parent;
if(!parent) return;
parent->m_children.append(this);
}
~QObject() {
foreach(QObject *o, m_children) delete o;
m_children.clear();
setParent(0);
}
private:
QList<QObject*> m_children;
QObject *m_parent;
};

Q_OBJECT macro is irrelevant here.

stereoMatching
21st January 2011, 05:59
Thanks, but I still have some questions
1 : What is the meaning of inheritance of the QDialog?
2 : What make those widget and layout become the children of FindDialog?

Thank you

wysota
21st January 2011, 07:01
1 : What is the meaning of inheritance of the QDialog?
I don't understand your question.

2 : What make those widget and layout become the children of FindDialog?
setLayout() reparents the layout and all items it manages.

FelixB
21st January 2011, 08:12
1 : What is the meaning of inheritance of the QDialog?

The FindDialog is a dialog. By inheritance, the FindDialog behaves like a QDialog. You only have to define your custom behaviour.

nish
21st January 2011, 08:17
1 : What is the meaning of inheritance of the QDialog?


at your first question i gave you the benefit of doubt, but this question proves that you need to learn a little bit of C++ before going into Qt. This really helps.

stereoMatching
21st January 2011, 08:40
I don't understand your question.
I mean, what kind of situations should I inherit the QDialog?
what is the jobs QDialog do for me in this FindDialog class?
when should I inherit the QDialog?
The book just inherit it anyway...
I don't even know what jobs(behavior) of the QDialog could do for me



setLayout() reparents the layout and all items it manages.

so the
setLayout(mainLayout) would make those instances become the children of the
mainLayout?

nish
21st January 2011, 08:44
I mean, what is the jobs QDialog do for me in this FindDialog class?
Its giving you all the functions which are defined in QDialog class. The most important function is of showing/drawing the Window to the screen.


I mean, what kind of situations should I inherit the QDialog?
When u need a dialog like functionality


what is the jobs QDialog do for me in this FindDialog class?
when should I inherit the QDialog?
The book just inherit it anyway...
I don't even know what jobs(behavior) of the QDialog could do for me
i think i explained already

Zlatomir
21st January 2011, 09:42
Public inheritance is the same as Is a relationship, if you write:


class FindDialog : public QDialog //here is the inheritance part
{
Q_OBJECT
//rest of the class is extending the functionality of the QDialog class
public:
FindDialog(QWidget *parent = 0);

signals:
void findNext(const QString &str, Qt::CaseSensitivity cs);
void findPrevious(const QString &str, Qt::CaseSensitivity cs);

private slots:
void findClicked();
void enableFindButton(const QString &text);

private:
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
};

Your class will still behave like a QDialog (even like a QWidget see that you can pass your class pointer as a parent to other QWidgets or QWidget derived instances)

But mainly inheritance is used for extending the functionality of another class, and also when inherit from some class you can "redefine" some functions (the ones declared virtual and override is the term for that), but this is more a polymorphism topic, don't you love how OOP topics come together? ;)

Take a C++ book, make sure it contains OOP topics before you buy it, and there you will have a few chapters explaining this (since we can't do that in a forum post ;) we just give some ideas, but this requires a few chapters in a book)

stereoMatching
21st January 2011, 09:53
Thanks, I am not a master of OOP but I think I know what is "is a" relationship and "has a" relation ship
But I still can't figure out what is protected inheritance want to do

I only wonder what kind of behaviour the QDialog could give me and what time should I inherit it
And the previous post gave me the answer
I don't need to know how are they implement it(at least for now)

PS : I don't like to use inheritance in most of the time
I would prefer "has a" and "static polymorphism" rather than "dynamic polymorphism"

stampede
21st January 2011, 10:33
But I still can't figure out what is protected inheritance
It's a kind of "has-a" relationship with possibility to access protected members of contained object. There is more about it, but maybe better leave it alone for now, just focus on the basics.
If you are curious: private and protected inheritance (http://www.parashift.com/c++-faq-lite/private-inheritance.html)

stereoMatching
21st January 2011, 11:53
It's a kind of "has-a" relationship with possibility to access protected members of contained object. There is more about it, but maybe better leave it alone for now, just focus on the basics.
If you are curious: private and protected inheritance (http://www.parashift.com/c++-faq-lite/private-inheritance.html)

Thanks, but I don't think I would use any protected inheritance since public inheritance
and private inheritance(only some extreme cases would be considered) are capable to mimic most of the cases.