Interface, abstract class, QObject and concrete class



  • I know that the title seems a little bit confusing but I'm going to explain.

    I was reading a few codes here and I saw something curious:

    Imagine that I have an interface called FooInterface, an abstract class called AbstractBar that inherits FooInterface and a concrete class called Biz that inherits AbstractBar, it would be something like this:

    class FooInterface
    {
        virtual ~FooInterface() {};
    };
    Q_DECLARE_INTERFACE(FooInterface, "FooInterface/1.0")
    
    class AbstractBar : public QObject, public FooInterface
    {
        Q_OBJECT
        Q_INTERFACES(FooInterface)
    };
    
    class Biz : public AbstractClass
    {
        Q_OBJECT
    };
    
    1. I wanted to know the usage for the QObject in that case.
    2. I know that Qt has a way to prevent memory leaking passing the parent to QObject, in that case we don't have a constructor for that, an instance of Biz would leak without deleting?
    3. What if AbstractBar had a constructor with the QObject parenting, an instance of Biz would still leak?
    4. This example was taken from a system with plugins, QPluginLoader would take the instance as parent and delete it afterwards or it would be mess up?
    5. What is the best way to create this kind of structure? Interface, abstract class and concrete class in Qt?

  • Moderators

    1. I'm not sure I understand what you mean. Inheriting QObject makes the class part of the Qt's object model. The usage is whatever you want it to be.
    2. Class not having a constructor with parent parameter doesn't make it leak memory. Consider these examples:
    { //scope
       Biz foo;
    } //end of scope, foo is released, no leak
    
    Biz* foo = new Biz();
    delete foo; //deleted, no leak
    
    QObject* parent = new QObject();
    Biz* foo = new Biz();
    foo->setParent(parent);
    delete parent; //parent deletes its child, no leak
    
    Biz* foo = new Biz();
    connect(qApp, &QApplication::aboutToQuit, foo, &Biz::deleteLater); //deleted via connection, no leak
    

    Providing a constructor with parent is just a convention. It's a good convention and you should follow it but it's not strictly necessary.

    1. Even if you do provide such constructor no one prevents you to pass a nullptr there. Providing this constructor does not automagically make it safe. Someone needs to pass that parent there, but (as seen above) it's not the only way to manage lifetime.
    2. QPluginLoader loads a plugin and provides a root component via instance() method. What do you mean by "would take the instance as parent"?
    3. There's no "best way". There might be "good way for particular use case" but, as with all programming, there's no holy grail. If the example you gave works for you it works for you ;)

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.