Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How much does Qt last release internally and externally use smart pointers?
Forum Updated to NodeBB v4.3 + New Features

How much does Qt last release internally and externally use smart pointers?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 5 Posters 1.3k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mynickmynick
    wrote on last edited by mynickmynick
    #1

    I am totally new to Qt, so please be patient with me : can please somebody explain to me about the question in the subject: how much does Qt last release internally and externally use smart pointers? Above all I am interested to know, as a new Qt framework programmer and user, if I can handle Qt objects with smart pointers (or alternatively local stack storage (what used to be called auto storage)) or if I have to take care of all the uncomfortable new and delete handling. I think I saw in many examples/tutorials the use of the new operator and that rang my mind alarm bell. Thank you so much.

    Chris KawaC 1 Reply Last reply
    1
    • M mynickmynick

      I am totally new to Qt, so please be patient with me : can please somebody explain to me about the question in the subject: how much does Qt last release internally and externally use smart pointers? Above all I am interested to know, as a new Qt framework programmer and user, if I can handle Qt objects with smart pointers (or alternatively local stack storage (what used to be called auto storage)) or if I have to take care of all the uncomfortable new and delete handling. I think I saw in many examples/tutorials the use of the new operator and that rang my mind alarm bell. Thank you so much.

      Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      Qt is a big library and there's not just one way it manages lifetimes, depending on the type of objects involved. But generally the QObject derived classes are handled via parent/child or object tree model i.e. each object can be assigned a parent and when an object is deleted it deletes all of its children automatically. In that sense a parent is a smart object that handles its children lifetimes.

      how much does Qt last release internally and externally use smart pointers?

      Well it depends on your definition of smart pointers. If you mean a specific type like std::unique_ptr then almost none in the API. The way Qt is designed there's just no need for it. Internally is a different story, probably quite a lot, but, like I said, Qt is a big library. Different modules have different needs. Qt itself provides a couple of pointer wrappers that you could call smart e.g. QSharedPointer, QWeakPointer, QPointer or QScopedPointer. Each has its own usages, but they are not used as a main way to handle Qt objects lifetimes.

      if I can handle Qt objects with smart pointers

      Qt is not designed around smart pointers, so although you could use them to some extent (e.g. for root nodes in the object tree) it would lead to more trouble than it's worth. As mentioned above the main object lifetime mechanism in Qt is the parent/child relation.

      or if I have to take care of all the uncomfortable new and delete handling

      What exactly makes you uncomfortable about them?

      I think I saw in many examples/tutorials the use of the new operator

      A typical Qt app has a root object created on the stack and then its children added with new. When the stack based root goes out of scope it is destroyed along with all its children, so you will rarely see a delete. A child can be destroyed explicitly by calling delete on the pointer, calling deleteLater() method, which is usually combined with Qt's signal/slot mechanism, or implicitly by its parent. In any case you have to make effort or completely ignore basic language principles to actually leak something.

      and that rang my mind alarm bell

      Why? It's a perfectly good language construct. Don't let the "oh no, naked new!" fear mongers get to you. The important thing is a solid model of lifetime management and Qt has one. It's just not based on smart pointers.

      M Z 2 Replies Last reply
      4
      • S Offline
        S Offline
        SimonSchroeder
        wrote on last edited by
        #3

        @Chris-Kawa already said it quite well.

        I know that with the advent of modern C++ we are told that you should never user a naked new. Problem is that Qt predates modern C++. It was long before proper smart pointers were known. Hence, Qt looked for a way around it. Furthermore, object oriented design was quite new and Qt tried to nail the theory perfectly. This all influenced the original design of Qt. Qt has not moved away from this design as it would break backwards compatibility.

        Everything inside the GUI (now talking about QWidgets, not necessarily QML) if used together with layouts automatically reparents to the containing widget. This takes over ownership of the widgets. Usually, your main window will be on the stack (and thus deleted on exiting the app) and everything else is related to this and thus also deleted. Most of the time dialogs can also be created on the stack. This is why you will (almost) never find a delete in proper Qt code.

        Note that this does not apply to non-GUI related things like containers, strings, etc. If you store pointers inside a container you are back to plain C++ rules (if the pointers are not pointers to GUI widgets or similar).

        1 Reply Last reply
        1
        • Chris KawaC Chris Kawa

          Qt is a big library and there's not just one way it manages lifetimes, depending on the type of objects involved. But generally the QObject derived classes are handled via parent/child or object tree model i.e. each object can be assigned a parent and when an object is deleted it deletes all of its children automatically. In that sense a parent is a smart object that handles its children lifetimes.

          how much does Qt last release internally and externally use smart pointers?

          Well it depends on your definition of smart pointers. If you mean a specific type like std::unique_ptr then almost none in the API. The way Qt is designed there's just no need for it. Internally is a different story, probably quite a lot, but, like I said, Qt is a big library. Different modules have different needs. Qt itself provides a couple of pointer wrappers that you could call smart e.g. QSharedPointer, QWeakPointer, QPointer or QScopedPointer. Each has its own usages, but they are not used as a main way to handle Qt objects lifetimes.

          if I can handle Qt objects with smart pointers

          Qt is not designed around smart pointers, so although you could use them to some extent (e.g. for root nodes in the object tree) it would lead to more trouble than it's worth. As mentioned above the main object lifetime mechanism in Qt is the parent/child relation.

          or if I have to take care of all the uncomfortable new and delete handling

          What exactly makes you uncomfortable about them?

          I think I saw in many examples/tutorials the use of the new operator

          A typical Qt app has a root object created on the stack and then its children added with new. When the stack based root goes out of scope it is destroyed along with all its children, so you will rarely see a delete. A child can be destroyed explicitly by calling delete on the pointer, calling deleteLater() method, which is usually combined with Qt's signal/slot mechanism, or implicitly by its parent. In any case you have to make effort or completely ignore basic language principles to actually leak something.

          and that rang my mind alarm bell

          Why? It's a perfectly good language construct. Don't let the "oh no, naked new!" fear mongers get to you. The important thing is a solid model of lifetime management and Qt has one. It's just not based on smart pointers.

          M Offline
          M Offline
          mynickmynick
          wrote on last edited by mynickmynick
          #4

          @Chris-Kawa thank you I will study this mechanism parent/child. Could you suggest a link for that? Just to answer your question I hardly ever use new - delete with naked pointers as it's slightly memory leak prone, in general. I prefer to allocate static or on the stack or via shared or unique (smart) pointers as it ensures the RAII principle and (nearly) always clean allocation ( you do not have to worry to ensure always a matching delete for any new) but never mind I will just study the matter.

          @SimonSchroeder Thanks yes as I said I need to study this parent/child scheme (a link suggestion would be very appreciated). Yes I am glad you pointed out these "historical" explanations as they better help me to understand and confirm my suspects. Qt indeed seems to be much more than a framework or library, on the C++ side it's like a language extension or language branch ;)

          Chris KawaC 1 Reply Last reply
          0
          • M mynickmynick

            @Chris-Kawa thank you I will study this mechanism parent/child. Could you suggest a link for that? Just to answer your question I hardly ever use new - delete with naked pointers as it's slightly memory leak prone, in general. I prefer to allocate static or on the stack or via shared or unique (smart) pointers as it ensures the RAII principle and (nearly) always clean allocation ( you do not have to worry to ensure always a matching delete for any new) but never mind I will just study the matter.

            @SimonSchroeder Thanks yes as I said I need to study this parent/child scheme (a link suggestion would be very appreciated). Yes I am glad you pointed out these "historical" explanations as they better help me to understand and confirm my suspects. Qt indeed seems to be much more than a framework or library, on the C++ side it's like a language extension or language branch ;)

            Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @mynickmynick I posted a link in my previous response, but here it is again: Object Trees & Ownership. There's really not that much to it. Each QObject holds a pointer to a parent object and a list of children. Destructor of QObject deletes all of its children.

            M 1 Reply Last reply
            3
            • Chris KawaC Chris Kawa

              @mynickmynick I posted a link in my previous response, but here it is again: Object Trees & Ownership. There's really not that much to it. Each QObject holds a pointer to a parent object and a list of children. Destructor of QObject deletes all of its children.

              M Offline
              M Offline
              mynickmynick
              wrote on last edited by
              #6

              @Chris-Kawa great, thanks, sorry I had not seen the link before

              1 Reply Last reply
              0
              • M mynickmynick has marked this topic as solved on
              • Chris KawaC Chris Kawa

                Qt is a big library and there's not just one way it manages lifetimes, depending on the type of objects involved. But generally the QObject derived classes are handled via parent/child or object tree model i.e. each object can be assigned a parent and when an object is deleted it deletes all of its children automatically. In that sense a parent is a smart object that handles its children lifetimes.

                how much does Qt last release internally and externally use smart pointers?

                Well it depends on your definition of smart pointers. If you mean a specific type like std::unique_ptr then almost none in the API. The way Qt is designed there's just no need for it. Internally is a different story, probably quite a lot, but, like I said, Qt is a big library. Different modules have different needs. Qt itself provides a couple of pointer wrappers that you could call smart e.g. QSharedPointer, QWeakPointer, QPointer or QScopedPointer. Each has its own usages, but they are not used as a main way to handle Qt objects lifetimes.

                if I can handle Qt objects with smart pointers

                Qt is not designed around smart pointers, so although you could use them to some extent (e.g. for root nodes in the object tree) it would lead to more trouble than it's worth. As mentioned above the main object lifetime mechanism in Qt is the parent/child relation.

                or if I have to take care of all the uncomfortable new and delete handling

                What exactly makes you uncomfortable about them?

                I think I saw in many examples/tutorials the use of the new operator

                A typical Qt app has a root object created on the stack and then its children added with new. When the stack based root goes out of scope it is destroyed along with all its children, so you will rarely see a delete. A child can be destroyed explicitly by calling delete on the pointer, calling deleteLater() method, which is usually combined with Qt's signal/slot mechanism, or implicitly by its parent. In any case you have to make effort or completely ignore basic language principles to actually leak something.

                and that rang my mind alarm bell

                Why? It's a perfectly good language construct. Don't let the "oh no, naked new!" fear mongers get to you. The important thing is a solid model of lifetime management and Qt has one. It's just not based on smart pointers.

                Z Offline
                Z Offline
                zonman
                wrote on last edited by zonman
                #7

                @Chris-Kawa thanks a lot for your answer, it is really helpful to understand this memory management in qt. But I have two more questions to this topic.

                1. What about std::unique_ptr vs QScopedPointer? As I understand, QScopedPointer does not need now and you can use std::unqiue_ptr in each case. It is more about old C++. Am I correct?
                  For example this description
                  https://stackoverflow.com/questions/40346393/should-i-use-qscopedpointer-or-stdunique-ptr

                2. Why do we need explicitly call delete in destructor for .ui class, in qt template for new project? We already have object tree hierarchy and use "this" in ui->setupUi(this). So we connected widtgets with parent. And if I remove delete from destructors, children destructors will still be called.
                  For example, this qt template, which generate on "new project":
                  mainwindow.h

                QT_BEGIN_NAMESPACE
                namespace Ui { class MainWindow; }
                QT_END_NAMESPACE
                
                class MainWindow : public QMainWindow
                
                {
                    Q_OBJECT
                
                public:
                    MainWindow(QWidget *parent = nullptr);
                    ~MainWindow();
                
                private:
                    Ui::MainWindow *ui;
                };
                

                "mainwindow.cpp

                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                }```
                
                ![Screenshot 2023-04-11 113823.png](https://ddgobkiprc33d.cloudfront.net/9b976f4a-29dc-4d07-98af-30086bf7427a.png)
                M 1 Reply Last reply
                0
                • Z zonman

                  @Chris-Kawa thanks a lot for your answer, it is really helpful to understand this memory management in qt. But I have two more questions to this topic.

                  1. What about std::unique_ptr vs QScopedPointer? As I understand, QScopedPointer does not need now and you can use std::unqiue_ptr in each case. It is more about old C++. Am I correct?
                    For example this description
                    https://stackoverflow.com/questions/40346393/should-i-use-qscopedpointer-or-stdunique-ptr

                  2. Why do we need explicitly call delete in destructor for .ui class, in qt template for new project? We already have object tree hierarchy and use "this" in ui->setupUi(this). So we connected widtgets with parent. And if I remove delete from destructors, children destructors will still be called.
                    For example, this qt template, which generate on "new project":
                    mainwindow.h

                  QT_BEGIN_NAMESPACE
                  namespace Ui { class MainWindow; }
                  QT_END_NAMESPACE
                  
                  class MainWindow : public QMainWindow
                  
                  {
                      Q_OBJECT
                  
                  public:
                      MainWindow(QWidget *parent = nullptr);
                      ~MainWindow();
                  
                  private:
                      Ui::MainWindow *ui;
                  };
                  

                  "mainwindow.cpp

                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent)
                      , ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      delete ui;
                  }```
                  
                  ![Screenshot 2023-04-11 113823.png](https://ddgobkiprc33d.cloudfront.net/9b976f4a-29dc-4d07-98af-30086bf7427a.png)
                  M Offline
                  M Offline
                  mpergand
                  wrote on last edited by
                  #8

                  @zonman said in How much does Qt last release internally and externally use smart pointers?:

                  Why do we need explicitly call delete in destructor for .ui class, in qt template for new project? We already have object tree hierarchy and use "this" in ui->setupUi(this).

                  Look at ui_MainWindow.h in the build folder, you will see that Ui::MainWindow class doesn't inherit from QObject, so in setupUi(this) "this" doesn't refer to some parent at all.

                  Z 1 Reply Last reply
                  1
                  • M mpergand

                    @zonman said in How much does Qt last release internally and externally use smart pointers?:

                    Why do we need explicitly call delete in destructor for .ui class, in qt template for new project? We already have object tree hierarchy and use "this" in ui->setupUi(this).

                    Look at ui_MainWindow.h in the build folder, you will see that Ui::MainWindow class doesn't inherit from QObject, so in setupUi(this) "this" doesn't refer to some parent at all.

                    Z Offline
                    Z Offline
                    zonman
                    wrote on last edited by
                    #9

                    @mpergand thank you for answer. But our MainWindow inherits from QMainWindow and we use ui->setupUi(this) inside our constructor (this - MainWindow class). So we have Qwidget pointer "this" inside initialize methods in Ui::MainWindow. And all our widgets destructors(from ui file) will be called without "delete ui"

                    M Chris KawaC 2 Replies Last reply
                    0
                    • Z zonman

                      @mpergand thank you for answer. But our MainWindow inherits from QMainWindow and we use ui->setupUi(this) inside our constructor (this - MainWindow class). So we have Qwidget pointer "this" inside initialize methods in Ui::MainWindow. And all our widgets destructors(from ui file) will be called without "delete ui"

                      M Offline
                      M Offline
                      mpergand
                      wrote on last edited by mpergand
                      #10

                      @zonman said in How much does Qt last release internally and externally use smart pointers?:

                      And all our widgets destructors(from ui file) will be called without "delete ui"

                      delete ui has nothing to do with the MainWindow interface, it only deletes the ui::MainWindow instance, if you don't do that you have a memory leak.

                      1 Reply Last reply
                      1
                      • Z zonman

                        @mpergand thank you for answer. But our MainWindow inherits from QMainWindow and we use ui->setupUi(this) inside our constructor (this - MainWindow class). So we have Qwidget pointer "this" inside initialize methods in Ui::MainWindow. And all our widgets destructors(from ui file) will be called without "delete ui"

                        Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by Chris Kawa
                        #11

                        @zonman As @mpergand said MainWindow and Ui::MainWindow are two different classes. Ui::MainWindow is a simple "container" class for the widgets set up in the designer. An instance of that class is needed to access them easily. It's not a QObject derived class and does not participate in the parent/child relations.

                        That being said there's no restrictions on how to use that class.
                        Qt wizard uses pointer approach, but if you're allergic to new/delete you can use a smart pointer, so you don't need to delete it explicitly:

                        class MainWindow : public QMainWindow
                        {
                           ...
                           std::unique_ptr<Ui::MainWindow> ui;
                        };
                        
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                            , ui(std::make_unique<Ui::MainWindow>())
                        {
                            ui->setupUi(this);
                           ...
                        

                        or you can use it as a direct member:

                        class MainWindow : public QMainWindow
                        {
                           ...
                           Ui::MainWindow ui;
                        };
                        
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                        {
                            ui.setupUi(this);
                           ...
                        

                        although not nice thing about that is you need to include the generated header ui_mainwindow.h in MainWindow header. I wouldn't recommend it, but it's an option.

                        The Ui::MainWindow is just a bag of pointers, so If you do all your setup in the constructor and don't need to access the widgets through the ui variable later on you can even use it entirely locally in the constructor:

                        class MainWindow : public QMainWindow
                        {
                           ...
                           // no ui member at all
                        };
                        
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                        {
                           Ui::MainWindow().setupUi(this);
                           ...
                        
                        1 Reply Last reply
                        3

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved