I'm new to Qt and I'm reading several Qt Projects to get the basics. While browsing the different classes it seems that pointers to QWidget are always used.
Exemple :
class ExempleWidget : public QWidget
{
Q_OBJECT
public:
ExempleWidget();
~ExempleWidget();
private:
QPushButton * m_stopButton;
QPushButton * m_playButton;
QHBoxLayout * m_hBoxLayout;
QVBoxLayout * m_vBoxLayout;
};
Is there any reason for using pointers for 'QPushButton' *'QHBoxLayout'* etc. ? Can we just use values so we don't have to bother with 'new' and 'delete'? Well I know we can but is it a good way to do it?
E.g.
private:
QPushButton m_stopButton;
EDIT :
All answers seems to point out the hierarchy between Qt classes. It's a good enough reason for me and I don't doubt of the point but let's say that there is no link between the widgets of my class (*m_stopButton* and *m_playButton*).
I can safely declare them as values in this case, can't I? When the class will be deleted, the members will be deleted too so pointers or not we will have the same behavior.
You'd want to use the pointers when you wish have full control over the object's lifetime. For example
If you want to construct a class member at some point after the initialization list in the constructor has been processed.
If you want to destruct a class member at some point before the compiler-generated destructor epilogue runs.
It is perfectly safe not to use the pointers when you are OK with the compiler constructing and destructing the object instances for you.
Raw pointers turn out to be error-prone whenever they own the resource they point to: it's an error to forget to delete the owned resource, to delete the resource multiple times, or to dereference an already-deleted resource.
Use of raw pointers (as opposed to smart pointers) that do not own the resource - when the resource will be freed by someone else - may still be a case of premature optimization. The use of raw pointers is prone to turn "small" code changes into resource leaks:
class X : public QObject {
QObject * a;
public:
// OK
X() : a(new QObject(this)) {}
// an error - we need to add a destructor that deletes a
X() : a(new QObject) {}
}
class X : public QObject P
QScopedPointer<QObject> a;
public:
// Both OK
X() : a(new QObject(this)) {}
X() : a(new QObject) {}
};
The smart pointers - C++11's std::unique_ptr
, Qt 4.6's QScopedPointer
- guarantee that the deletion always happens, and that access to a deleted resource is equivalent to a null pointer dereference and thus nominally caught and signaled by the processor hardware.
In C++, the order of construction and destruction of class members and automatic variables is fixed. In the examples below, the construction order is always a
then b
, and the destruction order is always b
then a
. This is very important.
class C {
A a;
B b;
};
void test() {
A a;
B b;
}
Thus, the following code is valid and behaves correctly under at least Qt 3, Qt 4 and Qt 5, unless specified otherwise.
class C : public QWidget {
QWidget a;
QLabel b;
public:
C(QWidget * parent = 0) : QWidget(parent), a(this), b(&a) {}
}
// Qt 4.6 & up only
class C : public QWidget {
QScopedPointer<QWidget> a;
QScopedPointer<QLabel> b;
public:
C(QWidget * parent = 0) : QWidget(parent),
a(new QWidget(this)),
b(new QLabel(a.data())) {}
};
// C++11 only
class C : public QWidget {
std::unique_ptr<QWidget> a;
std::unique_ptr<QLabel> b;
public:
C(QWidget * parent = 0) : QWidget(parent),
a(new QWidget(this)),
b(new QLabel(a.data())) {}
};
void test() {
QWidget c;
QWidget a(&c);
QLabel b(&a);
}
In all cases, the construction order is: c, a, b
; the destruction order is: b, a, c
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With