2

I am new to Qt5 and I am learning QWidgets to develop an application.

I've noticed in many examples, QWidgets are almost always accessed by pointer. For example:

#include <QApplication>
#include <QWidget>
#include <QFrame>
#include <QGridLayout>

class Cursors : public QWidget {

 public:
     Cursors(QWidget *parent = 0);
};

Cursors::Cursors(QWidget *parent)
    : QWidget(parent) {

  QFrame *frame1 = new QFrame(this);
  frame1->setFrameStyle(QFrame::Box);
  frame1->setCursor(Qt::SizeAllCursor);

  QFrame *frame2 = new QFrame(this);
  frame2->setFrameStyle(QFrame::Box);
  frame2->setCursor(Qt::WaitCursor);

  QFrame *frame3 = new QFrame(this);
  frame3->setFrameStyle(QFrame::Box);
  frame3->setCursor(Qt::PointingHandCursor);

  QGridLayout *grid = new QGridLayout(this);
  grid->addWidget(frame1, 0, 0);
  grid->addWidget(frame2, 0, 1);
  grid->addWidget(frame3, 0, 2);

  setLayout(grid);
}

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

  QApplication app(argc, argv);  

  Cursors window;

  window.resize(350, 150);
  window.setWindowTitle("Cursors");
  window.show();

  return app.exec();
}

This is taken from the tutorial: http://zetcode.com/gui/qt5/firstprograms/

Yet, on the same page, I see that we can access the QWidget base class by its object itself:

#include <QApplication>
#include <QWidget>

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

    QApplication app(argc, argv);

    QWidget window;

    window.resize(250, 150);
    window.setWindowTitle("Simple example");
    window.show();

    return app.exec();
}

Why is it necessary to access all QWidget derived classes by their pointer? Why isn't it necessary to access QWidget itself by its pointer?

shortstheory
  • 470
  • 5
  • 17
  • Neither one is necessary. It might be just easier to create local variables inside a class method, rather than declaring a bunch of member variables you will only be accessing once. And since you need the widgets to survive beyond the method's scope, you initialize them with `new`. See [object trees & ownership](http://doc.qt.io/qt-5/objecttrees.html). – thuga Nov 12 '15 at 07:39

3 Answers3

5

It's all about object's lifetime and shared ownership. If you create an object on stack in function, it will be destroyed when scope ends.

Why isn't it necessary to access QWidget by pointer in your example? Just because when main() 'ends', your program is finished, and widget may be destroyed.

Why is it necessary to access QWidget's children by pointer? Because if you want to ask QWidget to give you access to it's child, it can't give you a value, because it would be just a copy of an object. Moreover, if you pass a large object by value to QWidget, it needs to copy your object.

V. Kravchenko
  • 1,859
  • 10
  • 12
5

This is not specific to QWidgets: it is so for every QObjects (Qt fundamental base class, from which everything else is derived).

It is the consequence of a design choice of the Qt framework. Quoting Qt documentation:

QObject has neither a copy constructor nor an assignment operator. This is by design.

[...]

The main consequence is that you should use pointers to QObject (or to your QObject subclass) where you might otherwise be tempted to use your QObject subclass as a value. For example, without a copy constructor, you can't use a subclass of QObject as the value to be stored in one of the container classes. You must store pointers.

Source:

http://doc.qt.io/qt-5.5/qobject.html#no-copy-constructor

The rationale for this choice is explained here:

http://doc.qt.io/qt-5.5/object.html#identity-vs-value

jbm
  • 3,063
  • 1
  • 16
  • 25
3

QClasses are larger in size and you don't want to fill up your stack memory by instantiating them in stack memory.

When you instantiate derived class objects it also runs constructor of a base class ( derived class + base class ) memory is required,

On the other hand QWidget only inherits QObject and QPaintDevice as you can see here

So it will be less overhead to create QWidget object on stack memory.

You must be very careful when you are using heap memory, read the answers on memory management

You can study the difference between stack and heap from here

Community
  • 1
  • 1
Abdul Rehman
  • 1,687
  • 18
  • 31
  • 2
    A class could have several members of QWidget based objects that don't need to be pointers and they still won't be on stack, as long as the _owning_ object is not on the stack. And in that case the members and methods of the QWidget based object would not be access by pointer. e.g. `myApplication->frame1.setCursor(Qt::PointingHandCursor)` or within the object `myApplication` it would just be `frame1.setCursor(Qt::PointingHandCursor)` – t.niese Nov 12 '15 at 06:35
  • Good practice to create objects on the heap? That's quite a broad statement. – Mitch Nov 12 '15 at 07:38
  • Create objects on heap and their pointers on stack. e.g unique_ptr or shared_ptr – Abdul Rehman Nov 12 '15 at 07:42
  • 1
    But it's unnecessary for short-lived objects, amongst other things. – Mitch Nov 12 '15 at 07:55