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. Interfaces, abstract, concrete classes and QObject
QtWS25 Last Chance

Interfaces, abstract, concrete classes and QObject

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 5 Posters 11.0k Views
  • 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.
  • D Offline
    D Offline
    Defohin
    wrote on 25 Jan 2017, 05:55 last edited by
    #1

    I know that the tittle might sound confusing, but I come from languages that isn't strongly typed as C++ and it made me a little bit confused when changed to C++.
    I know also that it might have nothing to do with Qt as it's a C++ question, but Qt is made using C++ and this is the only place I know to ask such as question without people throwing stones at me (read Stack Overflow).
    Imagine that I have a class called AbstractFoo and two classes that inherits from that abstract class: Bar and Biz.
    I want to create a method that accepts FooInterface as parameter, I tried to use const AbstractFoo &foo but I got an error when I try to use a method saying that can't convert this to const. I figured I had to use pointers and it works just fine, but now it comes the problem that is planted in my mind, I have to avoid leaks, I always think that and I remember about the QObject.
    It's common for me to see in examples using abstract classes or interfaces inheriting from QObject but I don't see why they do that. For example, imagine that in my classes mentioned above AbstractFoo inherits from QObject, what is it for? Most of the examples I see is like that and they don't use the QObject, as least I think they don't. They don't use the parent thing to prevent leaking.
    The real question is: How to work with interfaces, abstract classes and concrete classes, where methods can accepted the interface and don't leak the pointer in Qt? (where does QObject enters?)

    V 1 Reply Last reply 25 Jan 2017, 08:10
    0
    • D Offline
      D Offline
      dheerendra
      Qt Champions 2022
      wrote on 25 Jan 2017, 06:13 last edited by
      #2

      Honestly too descriptive to answer your question. How about providing simple sample program of your question ? This helps us answer better.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      D 1 Reply Last reply 25 Jan 2017, 07:31
      3
      • D dheerendra
        25 Jan 2017, 06:13

        Honestly too descriptive to answer your question. How about providing simple sample program of your question ? This helps us answer better.

        D Offline
        D Offline
        Defohin
        wrote on 25 Jan 2017, 07:31 last edited by
        #3

        @dheerendra I don't think there's more than this:

        class FooInterface {
        public:
            virtual public say() = 0;
            virtual public hello() = 0;
        };
        
        class BarAbstract : public QObject, public FooInterface {
        public:
            virtual public hello() {
                qDebug() << "hello from abstract";
            };
        };
        
        class Biz : public BarAbstract {
        public:
            public say() {
                qDebug() << "hello from biz";
            };
        };
        
        class Bez : public BarAbstract {
        public:
            public say() {
                qDebug() << "hello from bez";
            };
        };
        
        void call(FooInterface *foo) {
            foo->hello();
            foo->say();
        }
        
        Bez *bez = new Bez;
        
        call(bez);
        

        I don't know if it's going to work, it's just an example of code.
        I see a lot of codes like that, the abstract class inheriting from QObject but it doesn't make use of the parent thing to avoid leaking, etc.

        1 Reply Last reply
        0
        • D Defohin
          25 Jan 2017, 05:55

          I know that the tittle might sound confusing, but I come from languages that isn't strongly typed as C++ and it made me a little bit confused when changed to C++.
          I know also that it might have nothing to do with Qt as it's a C++ question, but Qt is made using C++ and this is the only place I know to ask such as question without people throwing stones at me (read Stack Overflow).
          Imagine that I have a class called AbstractFoo and two classes that inherits from that abstract class: Bar and Biz.
          I want to create a method that accepts FooInterface as parameter, I tried to use const AbstractFoo &foo but I got an error when I try to use a method saying that can't convert this to const. I figured I had to use pointers and it works just fine, but now it comes the problem that is planted in my mind, I have to avoid leaks, I always think that and I remember about the QObject.
          It's common for me to see in examples using abstract classes or interfaces inheriting from QObject but I don't see why they do that. For example, imagine that in my classes mentioned above AbstractFoo inherits from QObject, what is it for? Most of the examples I see is like that and they don't use the QObject, as least I think they don't. They don't use the parent thing to prevent leaking.
          The real question is: How to work with interfaces, abstract classes and concrete classes, where methods can accepted the interface and don't leak the pointer in Qt? (where does QObject enters?)

          V Offline
          V Offline
          VRonin
          wrote on 25 Jan 2017, 08:10 last edited by VRonin
          #4

          @Defohin said in Interfaces, abstract, concrete classes and QObject:

          I tried to use const AbstractFoo &foo but I got an error when I try to use a method saying that can't convert this to const

          The problem does not come from what you think. const AbstractFoo & can only use const methods inside AbstractFoo. changing to:

          class FooInterface {
          public:
              virtual public say() const = 0;
              virtual public hello() const = 0;
          };
          

          will fix your problem. const methods are pretty important. as a general rule, if the method does not change members of the class it should be declared const

          magine that in my classes mentioned above AbstractFoo inherits from QObject, what is it for?

          The uses are numerous, the most important ones:

          • use parent-child to handle lifecycle
          • ability to use signals and slots
          • ability to expose the class to QML
          • QObject::tr() to mark translatable strings

          don't leak the pointer

          You don't leak the pointer, you leak the memory pointed too. The solution from the current standard is to use smart pointers. This is the flowchart I normally follow, it covers 99% of the cases:

          • is it a QObject?
            • yes
              • can you give it a parent? (for example moveToThread() prevents the parent-child relationship)
                • yes: use a normal pointer and set the parent
                • no: connect the deleteLater() slot to some signal
            • no
              • can multiple places share ownership of the object or pass ownership from one another? (e.g. in containes)
                • yes: use std::shared_ptr
                • no: use std::unique_ptr

          If you need to use the pointer in a function that should not manage ownership but just access (read/write) the object (this covers 90% of use cases) then use a raw pointer argument (use std::unique_ptr::get() or std::shared_ptr::get() to retrieve the raw pointer from smart pointers)


          References to avoid being eaten alive by C++ purists for what I just said:
          Bjarne Stroustrup - A Tour of C++
          Scott Meyers - Effective Modern C++
          Herb Sutter - Back to the Basics! Essentials of Modern C++ Style

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          D 1 Reply Last reply 25 Jan 2017, 14:50
          4
          • V VRonin
            25 Jan 2017, 08:10

            @Defohin said in Interfaces, abstract, concrete classes and QObject:

            I tried to use const AbstractFoo &foo but I got an error when I try to use a method saying that can't convert this to const

            The problem does not come from what you think. const AbstractFoo & can only use const methods inside AbstractFoo. changing to:

            class FooInterface {
            public:
                virtual public say() const = 0;
                virtual public hello() const = 0;
            };
            

            will fix your problem. const methods are pretty important. as a general rule, if the method does not change members of the class it should be declared const

            magine that in my classes mentioned above AbstractFoo inherits from QObject, what is it for?

            The uses are numerous, the most important ones:

            • use parent-child to handle lifecycle
            • ability to use signals and slots
            • ability to expose the class to QML
            • QObject::tr() to mark translatable strings

            don't leak the pointer

            You don't leak the pointer, you leak the memory pointed too. The solution from the current standard is to use smart pointers. This is the flowchart I normally follow, it covers 99% of the cases:

            • is it a QObject?
              • yes
                • can you give it a parent? (for example moveToThread() prevents the parent-child relationship)
                  • yes: use a normal pointer and set the parent
                  • no: connect the deleteLater() slot to some signal
              • no
                • can multiple places share ownership of the object or pass ownership from one another? (e.g. in containes)
                  • yes: use std::shared_ptr
                  • no: use std::unique_ptr

            If you need to use the pointer in a function that should not manage ownership but just access (read/write) the object (this covers 90% of use cases) then use a raw pointer argument (use std::unique_ptr::get() or std::shared_ptr::get() to retrieve the raw pointer from smart pointers)


            References to avoid being eaten alive by C++ purists for what I just said:
            Bjarne Stroustrup - A Tour of C++
            Scott Meyers - Effective Modern C++
            Herb Sutter - Back to the Basics! Essentials of Modern C++ Style

            D Offline
            D Offline
            Defohin
            wrote on 25 Jan 2017, 14:50 last edited by
            #5

            @VRonin Thank you for y our answer.
            I have two questions based on your answer.

            1. If I use the parent thing with QObject it's on the abstract class, right? What about the concrete classes? How would that look like?
            2. The problem with the reference is that I can't create a class with all the methods as const, then pointers is the only way out, right?
            3. The deleteLater will be "activated" when it's out of scope or right at the moment I call it? For example, it's common to use deleteLater with QNetworkReply in a slot, if I call reply->deleteLater before I do a few things in that slot, will that delete or it's going to delete only when it's out of scope? (it's common for me to call deleteLater before 'cause I have a few if conditions and I don't want to be repeating deleteLater to every condition.
            1 Reply Last reply
            0
            • V Offline
              V Offline
              VRonin
              wrote on 25 Jan 2017, 15:26 last edited by
              #6
              1. All the derived classes of QObject have a setParent() method to set the parent, you don't have to do anything manually.
              2. The problem is not with the reference but with the const. const AbstractFoo& can only use const methods AbstractFoo& can use all methods
              3. as stated in http://doc.qt.io/qt-5/qobject.html#deleteLater

              The object will be deleted when control returns to the event loop.

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              D 1 Reply Last reply 25 Jan 2017, 16:16
              1
              • V VRonin
                25 Jan 2017, 15:26
                1. All the derived classes of QObject have a setParent() method to set the parent, you don't have to do anything manually.
                2. The problem is not with the reference but with the const. const AbstractFoo& can only use const methods AbstractFoo& can use all methods
                3. as stated in http://doc.qt.io/qt-5/qobject.html#deleteLater

                The object will be deleted when control returns to the event loop.

                D Offline
                D Offline
                Defohin
                wrote on 25 Jan 2017, 16:16 last edited by
                #7

                @VRonin A questions about your answer 1: It's common to see the parent thing on the constructor, imagine that the constructor with the parent thing is on the abstract class, how is the concrete class affected by that? And how to make usage of that?

                K 1 Reply Last reply 25 Jan 2017, 16:34
                0
                • D Defohin
                  25 Jan 2017, 16:16

                  @VRonin A questions about your answer 1: It's common to see the parent thing on the constructor, imagine that the constructor with the parent thing is on the abstract class, how is the concrete class affected by that? And how to make usage of that?

                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 25 Jan 2017, 16:34 last edited by kshegunov
                  #8

                  I'd like to expand a bit here on @VRonin's answer:

                  can you give it a parent? (for example moveToThread() prevents the parent-child relationship)

                  moveToThread() does not prevent the parent-child relationship. It, however, imposes the requirement (which is documented) that all objects in a given QObject hierarchy have the same thread affinity (this is mainly to prevent race conditions on object destruction). If one moves the root object of the tree to a given thread, then all children are moved to the same thread too.

                  yes: use std::shared_ptr

                  Only a note here. "Shared pointer" here implies that the object manages its own lifetime, so that's why mixing it with QObjects is a rather dubious decision in many cases (QObjects have a very well defined ownership). Also using a shared pointer does not actually share the object, it shares (as the name suggest) only the pointer to said object. There's a subtle difference when working in a threaded environment, where the pointer is safe for passing around (thread-wise) but the object is not, it's responsibility of the programmer to ensure no race conditions happen when working with the object.

                  The solution from the current standard is to use smart pointers.

                  The solution to what? My solution which is by no means contradicting the standard is to use stack-based allocation, which is faster, more robust and safer. I will yet again complain that someone saying you should always use smart pointers, doesn't necessarily sum up to a rule, or even a guideline, whomever that person might be ...

                  @Defohin

                  1. If I use the parent thing with QObject it's on the abstract class, right? What about the concrete classes? How would that look like?

                  C++ doesn't much distinguish here, abstract classes are still classes and have all the features regular classes have. So you can still have a class partially providing an implementation (e.g. constructors and such). The only restriction an abstract class imposes is that you can't have instances (objects) made out of it, because you have functions that are pure virtual (i.e. they don't have implementations).

                  A questions about your answer 1: It's common to see the parent thing on the constructor, imagine that the constructor with the parent thing is on the abstract class, how is the concrete class affected by that? And how to make usage of that?

                  Delegate to the parent class. Example follows:

                  class MyAbstractClass : public QObject
                  {
                      Q_OBJECT
                  
                  public:
                      MyAbstractClass(QObject * parent = Q_NULLPTR)
                          : QObject(parent) //< Will call the parent class' constructor first
                      {
                      }
                  
                      virtual void myPureVirtualMethod() = 0;
                  };
                  
                  class MyClass : public MyAbstractClass
                  {
                      Q_OBJECT
                  
                  public:
                      MyClass(QObject * parent = Q_NULLPTR)
                          : MyAbstractClass(parent) //< Will call the parent class' constructor first
                      {
                      }
                  
                      void myPureVirtualMethod() Q_DECL_OVERRIDE
                      {
                          //< We now provide implementation for that method, so we don't have an abstract class anymore
                      }
                  };
                  

                  Read and abide by the Qt Code of Conduct

                  V 1 Reply Last reply 25 Jan 2017, 16:49
                  3
                  • V Offline
                    V Offline
                    VRonin
                    wrote on 25 Jan 2017, 16:41 last edited by
                    #9

                    the usual way is to call the base constructor from the derived class.

                    in your case you have to define these constructors:

                    BarAbstract::BarAbstract(QObject* parent=0)
                    :QObject(parent)
                    // other initialisation
                    {/*constructor body*/}
                    Bez ::Bez (QObject* parent=0)
                    :BarAbstract(parent)
                    // other initialisation
                    {/*constructor body*/}
                    

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    1
                    • K kshegunov
                      25 Jan 2017, 16:34

                      I'd like to expand a bit here on @VRonin's answer:

                      can you give it a parent? (for example moveToThread() prevents the parent-child relationship)

                      moveToThread() does not prevent the parent-child relationship. It, however, imposes the requirement (which is documented) that all objects in a given QObject hierarchy have the same thread affinity (this is mainly to prevent race conditions on object destruction). If one moves the root object of the tree to a given thread, then all children are moved to the same thread too.

                      yes: use std::shared_ptr

                      Only a note here. "Shared pointer" here implies that the object manages its own lifetime, so that's why mixing it with QObjects is a rather dubious decision in many cases (QObjects have a very well defined ownership). Also using a shared pointer does not actually share the object, it shares (as the name suggest) only the pointer to said object. There's a subtle difference when working in a threaded environment, where the pointer is safe for passing around (thread-wise) but the object is not, it's responsibility of the programmer to ensure no race conditions happen when working with the object.

                      The solution from the current standard is to use smart pointers.

                      The solution to what? My solution which is by no means contradicting the standard is to use stack-based allocation, which is faster, more robust and safer. I will yet again complain that someone saying you should always use smart pointers, doesn't necessarily sum up to a rule, or even a guideline, whomever that person might be ...

                      @Defohin

                      1. If I use the parent thing with QObject it's on the abstract class, right? What about the concrete classes? How would that look like?

                      C++ doesn't much distinguish here, abstract classes are still classes and have all the features regular classes have. So you can still have a class partially providing an implementation (e.g. constructors and such). The only restriction an abstract class imposes is that you can't have instances (objects) made out of it, because you have functions that are pure virtual (i.e. they don't have implementations).

                      A questions about your answer 1: It's common to see the parent thing on the constructor, imagine that the constructor with the parent thing is on the abstract class, how is the concrete class affected by that? And how to make usage of that?

                      Delegate to the parent class. Example follows:

                      class MyAbstractClass : public QObject
                      {
                          Q_OBJECT
                      
                      public:
                          MyAbstractClass(QObject * parent = Q_NULLPTR)
                              : QObject(parent) //< Will call the parent class' constructor first
                          {
                          }
                      
                          virtual void myPureVirtualMethod() = 0;
                      };
                      
                      class MyClass : public MyAbstractClass
                      {
                          Q_OBJECT
                      
                      public:
                          MyClass(QObject * parent = Q_NULLPTR)
                              : MyAbstractClass(parent) //< Will call the parent class' constructor first
                          {
                          }
                      
                          void myPureVirtualMethod() Q_DECL_OVERRIDE
                          {
                              //< We now provide implementation for that method, so we don't have an abstract class anymore
                          }
                      };
                      
                      V Offline
                      V Offline
                      VRonin
                      wrote on 25 Jan 2017, 16:49 last edited by VRonin
                      #10

                      I was expecting a much harsher flame from you on this one, I got away easily! 😉

                      @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                      Only a note here. "Shared pointer" here implies that the object manages its own lifetime, so that's why mixing it with QObjects is a rather dubious decision

                      That's why it ends in the "is it a QObject?" -> "no:" section

                      @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                      he solution to what? My solution which is by no means contradicting the standard is to use stack-based allocation,

                      I did not explain myself clearly here. I meant the solution to raw pointers that act as owners of memory ending up lost. stack-based is of course a solution if you can allocate the object on the stack and arguably std::unique_ptr, at the end of the day, behaves like stack allocation in terms of memory management

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      K 1 Reply Last reply 25 Jan 2017, 16:54
                      0
                      • V VRonin
                        25 Jan 2017, 16:49

                        I was expecting a much harsher flame from you on this one, I got away easily! 😉

                        @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                        Only a note here. "Shared pointer" here implies that the object manages its own lifetime, so that's why mixing it with QObjects is a rather dubious decision

                        That's why it ends in the "is it a QObject?" -> "no:" section

                        @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                        he solution to what? My solution which is by no means contradicting the standard is to use stack-based allocation,

                        I did not explain myself clearly here. I meant the solution to raw pointers that act as owners of memory ending up lost. stack-based is of course a solution if you can allocate the object on the stack and arguably std::unique_ptr, at the end of the day, behaves like stack allocation in terms of memory management

                        K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 25 Jan 2017, 16:54 last edited by
                        #11

                        @VRonin said in Interfaces, abstract, concrete classes and QObject:

                        I was expecting a much harsher flame from you on this one, I got away easily! 😉

                        I must be loosing the magic touch then ... ;)

                        That's why it ends in the "is it a QObject?" -> "no:" section

                        Yes, I know, it was just a note, not a critique.

                        I did not explain myself clearly here. I meant the solution to raw pointers that act as owners of memory ending up lost. stack-based is of course a solution if you can allocate the object on the stack and arguably std::unique_ptr, at the end of the day, behaves like stack allocation in terms of memory management

                        It is in fact a stack allocation. You create an object in the stack, to manage a piece of memory. However many times (in Qt particulary) you don't care about any of those pointers. Qt doesn't throw from the constructor (or anywhere else in fact), so you can safely use raw pointers. There is no reason whatsoever to think that std::unique_ptr is better (or faster) than new and delete. The only thing it's good for is to be throw-safe (here I exclude the trivial forgotten delete).

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        0
                        • O Offline
                          O Offline
                          Oleksandr Malyushytskyy
                          wrote on 25 Jan 2017, 19:02 last edited by Oleksandr Malyushytskyy
                          #12

                          It might be not related to your question, but you need to specify type when you declare or define member functions:

                          public:
                          virtual public say() = 0;

                          should become

                          public:
                          virtual void say() = 0;

                          D 1 Reply Last reply 25 Jan 2017, 19:03
                          2
                          • O Oleksandr Malyushytskyy
                            25 Jan 2017, 19:02

                            It might be not related to your question, but you need to specify type when you declare or define member functions:

                            public:
                            virtual public say() = 0;

                            should become

                            public:
                            virtual void say() = 0;

                            D Offline
                            D Offline
                            Defohin
                            wrote on 25 Jan 2017, 19:03 last edited by Defohin
                            #13

                            @Oleksandr-Malyushytskyy It was a typing error, but thank you.

                            I'll be reading your answers later tonight with attention to understand everything.

                            Thank you all so far.

                            1 Reply Last reply
                            0
                            • O Offline
                              O Offline
                              Oleksandr Malyushytskyy
                              wrote on 25 Jan 2017, 19:21 last edited by
                              #14

                              QObject enters to the scene when you need signal/slots. Since QObject deletes its children you do not have worry about deleting QObjects which do have parents( unless it is required by workflow - like create dialog, show, it, delete it when closed).

                              Above means allocated on the stack QObject should not typically have a parent.

                              For everything else (including QObject instances without parent) the right answer for proper memory management is the same as for any C++ code - smart pointers (already mentioned above).

                              K 1 Reply Last reply 25 Jan 2017, 19:32
                              0
                              • O Oleksandr Malyushytskyy
                                25 Jan 2017, 19:21

                                QObject enters to the scene when you need signal/slots. Since QObject deletes its children you do not have worry about deleting QObjects which do have parents( unless it is required by workflow - like create dialog, show, it, delete it when closed).

                                Above means allocated on the stack QObject should not typically have a parent.

                                For everything else (including QObject instances without parent) the right answer for proper memory management is the same as for any C++ code - smart pointers (already mentioned above).

                                K Offline
                                K Offline
                                kshegunov
                                Moderators
                                wrote on 25 Jan 2017, 19:32 last edited by kshegunov
                                #15

                                @Oleksandr-Malyushytskyy said in Interfaces, abstract, concrete classes and QObject:

                                Above means allocated on the stack QObject should not typically have a parent.

                                Not true for QWidgets, where parent is important regardless of memory management. Dialogs without a parent have a native handle, while those that do have a parent are (ordinarily) alien widgets.

                                the right answer for proper memory management is the same as for any C++ code - smart pointers

                                Sorry, but no. Smart pointers aren't proper memory management, they are a tool that might facilitate proper management. These two things aren't one and the same. You can have proper memory management without ever in your code using smart pointers. C programs can have proper memory management, and they don't even have classes ...

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                0
                                • O Offline
                                  O Offline
                                  Oleksandr Malyushytskyy
                                  wrote on 25 Jan 2017, 19:43 last edited by Oleksandr Malyushytskyy
                                  #16

                                  @kshegunov

                                  Not true for QWidgets, where parent is important regardless of memory management. Dialogs without a parent have a native handle, while those that do have a parent are (ordinarily) alien widgets.

                                  • Any widget regardless of parent can have a native handle.
                                  • Providing a parent to the QObject allocated on the stack may lead to deleting it twice. So QWidget which needs a parents should not be allocated on a stack.

                                  Sorry, but no. Smart pointers aren't proper memory management, they are a tool that might facilitate proper management.

                                  • Smartpointers in C++ is basically only a way for an application to do a proper memory management in presence of exceptions.
                                  K 1 Reply Last reply 25 Jan 2017, 19:54
                                  0
                                  • O Oleksandr Malyushytskyy
                                    25 Jan 2017, 19:43

                                    @kshegunov

                                    Not true for QWidgets, where parent is important regardless of memory management. Dialogs without a parent have a native handle, while those that do have a parent are (ordinarily) alien widgets.

                                    • Any widget regardless of parent can have a native handle.
                                    • Providing a parent to the QObject allocated on the stack may lead to deleting it twice. So QWidget which needs a parents should not be allocated on a stack.

                                    Sorry, but no. Smart pointers aren't proper memory management, they are a tool that might facilitate proper management.

                                    • Smartpointers in C++ is basically only a way for an application to do a proper memory management in presence of exceptions.
                                    K Offline
                                    K Offline
                                    kshegunov
                                    Moderators
                                    wrote on 25 Jan 2017, 19:54 last edited by kshegunov
                                    #17

                                    @Oleksandr-Malyushytskyy said in Interfaces, abstract, concrete classes and QObject:

                                    Any widget regardless of parent can have a native handle.

                                    They can indeed, that's why I put "ordinarily" (i.e. usually) in parenthesis - most of the time they won't if you don't pass the appropriate attribute(s).

                                    Providing a parent to the QObject allocated on the stack may lead to deleting it twice.

                                    Yes, if you take special care not to put them in a stack order. A stack is first-in-last-out, so they (the objects) should be allocated in this fashion - parents come before children. Example:

                                    QObject parent;
                                    QObject child(&parent); //< Perfectly safe!
                                    
                                    QObject child;
                                    QObject parent;
                                    
                                    child.setParent(&parent); //< Bad idea, don't do it it like this.
                                    

                                    So QWidget which needs a parents should not be allocated on a stack.

                                    Absolutely wrong! You can allocate them on the stack however much you like.

                                    Smartpointers in C++ is basically only a way for an application to do a proper memory management in presence of exceptions.

                                    Yes, that's what I wrote two posts up. And again, it's a tool, it doesn't sum up to "proper memory management". You can achieve proper memory management, albeit verbose, without smart pointers too. Plus I already noted that for Qt specifically you don't have exceptions thrown from the library.

                                    Read and abide by the Qt Code of Conduct

                                    O 1 Reply Last reply 25 Jan 2017, 20:03
                                    1
                                    • K kshegunov
                                      25 Jan 2017, 19:54

                                      @Oleksandr-Malyushytskyy said in Interfaces, abstract, concrete classes and QObject:

                                      Any widget regardless of parent can have a native handle.

                                      They can indeed, that's why I put "ordinarily" (i.e. usually) in parenthesis - most of the time they won't if you don't pass the appropriate attribute(s).

                                      Providing a parent to the QObject allocated on the stack may lead to deleting it twice.

                                      Yes, if you take special care not to put them in a stack order. A stack is first-in-last-out, so they (the objects) should be allocated in this fashion - parents come before children. Example:

                                      QObject parent;
                                      QObject child(&parent); //< Perfectly safe!
                                      
                                      QObject child;
                                      QObject parent;
                                      
                                      child.setParent(&parent); //< Bad idea, don't do it it like this.
                                      

                                      So QWidget which needs a parents should not be allocated on a stack.

                                      Absolutely wrong! You can allocate them on the stack however much you like.

                                      Smartpointers in C++ is basically only a way for an application to do a proper memory management in presence of exceptions.

                                      Yes, that's what I wrote two posts up. And again, it's a tool, it doesn't sum up to "proper memory management". You can achieve proper memory management, albeit verbose, without smart pointers too. Plus I already noted that for Qt specifically you don't have exceptions thrown from the library.

                                      O Offline
                                      O Offline
                                      Oleksandr Malyushytskyy
                                      wrote on 25 Jan 2017, 20:03 last edited by
                                      #18

                                      @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                                      QObject parent;
                                      QObject child(&parent); //< Perfectly safe!

                                      You make an assumption that parent is allocated on a stack. Why? If it is not? If it is destroyed before child goes out of scope?

                                      I could continue to argue about other topics too, like if Qt code does not throw exceptions, it does not mean that exception may not be thrown in your application written with Qt or even from Qt code,
                                      but I believe this topic is not a right place for such discussion, since it not does not help person who asked a question, while my original answer I believe should have helped him.

                                      K 1 Reply Last reply 25 Jan 2017, 20:11
                                      0
                                      • V Offline
                                        V Offline
                                        VRonin
                                        wrote on 25 Jan 2017, 20:09 last edited by
                                        #19

                                        This is the type of flaming I was talking about!
                                        grabs popcorn

                                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                        ~Napoleon Bonaparte

                                        On a crusade to banish setIndexWidget() from the holy land of Qt

                                        1 Reply Last reply
                                        1
                                        • O Oleksandr Malyushytskyy
                                          25 Jan 2017, 20:03

                                          @kshegunov said in Interfaces, abstract, concrete classes and QObject:

                                          QObject parent;
                                          QObject child(&parent); //< Perfectly safe!

                                          You make an assumption that parent is allocated on a stack. Why? If it is not? If it is destroyed before child goes out of scope?

                                          I could continue to argue about other topics too, like if Qt code does not throw exceptions, it does not mean that exception may not be thrown in your application written with Qt or even from Qt code,
                                          but I believe this topic is not a right place for such discussion, since it not does not help person who asked a question, while my original answer I believe should have helped him.

                                          K Offline
                                          K Offline
                                          kshegunov
                                          Moderators
                                          wrote on 25 Jan 2017, 20:11 last edited by kshegunov
                                          #20

                                          The original topic did include a question about leaking or not memory, so memory management is indeed relevant, although we are running a bit off topic I will concede.

                                          You make an assumption that parent is allocated on a stack. Why? If it is not? If it is destroyed before child goes out of scope?

                                          Then I'd argue the child should be a member of said parent:

                                          class X : public QObject
                                          {
                                              X(QObject * parent)
                                                  : QObject(parent), child(this)
                                              {
                                              }
                                          
                                          private:
                                              QObject child;
                                          }
                                          

                                          it does not mean that exception may not be thrown in your application written with Qt or even from Qt code,

                                          Yes, and I did acknowledge that. Plus I reiterate, yet again, throw-safe code does not require smart pointers, they just make it easier to handle.

                                          I'd also like to introduce yet another consideration here:
                                          Creating a QObject (or derived class) instance with new (or equivalent std::make_unique, make_shared or w/e) amounts to allocating a void *, which is mighty inefficient.

                                          @VRonin Nice glasses!

                                          Read and abide by the Qt Code of Conduct

                                          V 1 Reply Last reply 25 Jan 2017, 20:19
                                          0

                                          10/25

                                          25 Jan 2017, 16:49

                                          • Login

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