Multiple inheritance in Qt



  • Here is my source code:
    Cal.h
    @
    #ifndef CAL_H
    #define CAL_H

    #include <QWidget>
    #include "update.h"

    class Calculator : public QWidget, public update
    {
    Q_OBJECT
    public:
    Calculator(QWidget *parent= 0);

    private slots:
    void transmit();

    };
    #endif
    @

    @//Cal.cpp
    #include "Cal.h"

    Calculator::Calculator(QWidget *parent)
    : QWidget(parent)
    {
    }
    @
    @//update.h
    #ifndef UPDATE_H
    #define UPDATE_H

    class update
    {
    public:
    update();
    void transmit();
    };
    #endif // UPDATE_H
    @
    @//update.cpp
    #include "update.h"
    #include <iostream>
    update::update()
    {
    }

    void update::transmit()
    {
    std::cout<<"SLOT function."<<'\n';

    }
    @

    As in Cal.h:

    An error occurs to this
    @class Calculator : public QWidget, public update@

    What I really want to do is to take update::transmit() function as the slot function of class Calculator.
    How can I do?
    I think I can declare and define the function update::transmit() in the update.h and update.cpp file, then inheritancing the header file to achieve my goal.
    Because I don't want to delcare and define every signal and slot function in the class * Calculator*. Seperating them out should be the correct method~
    But error message pops out. Please correct my fault, thank you!



  • Hi,

    I think, that:

    @
    //update.h
    #ifndef UPDATE_H
    #define UPDATE_H

    class update
    {
    public:
        update();
        private slots: void transmit();
    };
    #endif // UPDATE_H
    

    @

    and

    @

    #ifndef CAL_H
    #define CAL_H

    #include <QWidget>
    #include "update.h"

    class Calculator : public QWidget, public update
    {
    Q_OBJECT
    public:
    Calculator(QWidget *parent= 0);
    };
    #endif
    @

    and let you considering if you will have to override the "transmit()" method, you should declare it as virtual:
    @
    //update.h
    #ifndef UPDATE_H
    #define UPDATE_H

    class update
    {
    public:
        update();
        private slots: virtual void transmit();
    };
    #endif // UPDATE_H
    

    @



  • What the error message do you get?

    To make the "update" class to provide the slots you need to inherit it from QObject and declare Q_OBJECT inside the class.
    Without it moc compiler will not recognize your class and will not process "signals" and "slots" keywords.
    "Here is more info":http://qt-project.org/doc/qt-5/signalsandslots.html
    and "here is more detailed explanation":http://woboq.com/blog/how-qt-signals-slots-work.html

    @
    class update : piblic QObject
    {
    Q_OBJECT
    public:
    ...
    slots:
    void transmit();
    }
    @


  • Lifetime Qt Champion

    Hi,

    The problem is that if update is also a QObject, then the inheritance is not possible anymore since QWidget is also a QObject.



  • Technically it is possible to have the same base class in multiple inheritance. The solution is a "virtual inheritance":http://en.wikipedia.org/wiki/Virtual_inheritance. Unless Qt prevents it.
    But I prefer to avoid it.


  • Lifetime Qt Champion

    Qt doesn't prevent it, but here's two rules:

    You can't inherit from multiple QObject classes

    If you inherit from QObject, it must be the first class



  • bq. Qt doesn’t prevent it, but here’s two rules:

    And the rules prevents us to use multiple QObject inheritance :-)

    @Stallman: I think you don't have much choice here.

    • You need to declare and define all slots, signals in the class that is inherited from QObject and then call methods in the base class. Of course you will need to declare and define all these methods too.
    • If the "update" class updates the view and then you may consider to use "Model/View":https://qt-project.org/doc/qt-5/model-view-programming.html
    • Come up with some other design of your application.
    • Try to implement multiple QObject inheritance. Just for fun.


  • You have a diamond inheritance problem.

    This "link":http://qt-project.org/forums/viewthread/20044 should help you solve your problem.



  • ka510

    I think the code (the link you provided ) is not very straight to be understood.
    Any alternative idea to seperate the model and view class out?

    I saw a class which is written as below:
    @
    MainWindow::Private::Private( MainWindow * owner ):
    QObject(),
    owner( owner ),
    ui(),
    controller( new FileController( this ) ),
    ... //Lots of code
    @
    And he can seperate the defined function out.
    I don't know what does the code mean?
    And this:
    @::Private::Private():@

    It's weird but works...


  • Moderators

    Maybe more of a design change than a solution to this particular problem, but how about changing inheritance to composition?

    Should the ui widget really be an updater or rather have an updater like so:
    @
    class Calculator : public QWidget {
    ...
    update mUpdater;
    }
    @
    with some getters and setters etc. or maybe even use updater:
    @
    class Calculator : public QWidget {
    ...
    void updateWith(update*);
    }
    @

    This way you can connect to whatever you need and base them on whatever you need.
    I expressed this view several times but I think inheritance is one of the massively overused and under-designed thing in programs out there. A class shouldn't inherit everything just because it can. It should only do it when the class relation truly is a is relation.


Log in to reply
 

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