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 functionupdate::transmit()
in the update.h and update.cpp file, then inheritancing the header file to achieve my goal.
Because I don't want to declare and define every signal and slot function in theclass Calculator
. Separating 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.htmlclass update : public QObject { Q_OBJECT public: ... slots: void transmit(); }
-
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. -
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...
-
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.