June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

[SOLVED] [Class Inheritance] Need tips on creating a hierarchic class structure

 

Hi Qt Devs!

I know this is a really vague question, but this could become a major problem if I don’t ask this.

For my interface, I want to subclass QWidget to create specialized widgets. I want a widget for each item that I have in my DB (it sounds like a lot, but for my situation, I think this is the best solution). My items are organized in a tree-like structure, each category having similar properties.

So, I want to create an abstract class that contains very generic virtual member functions that apply to all tests. In turn, I want to have abstract, but further specialized, classes for all nodes in tree structure, down to the very bottom of the tree, where I want to have actual widgets that I can create instances of.

However, when I tried to do that with one class,

  1. #include "cqp.h"
  2.  
  3. CQp::CQp(QWidget *parent) :
  4.     QWidget(parent)
  5. {
  6. }

  1. #ifndef CQP_H
  2. #define CQP_H
  3.  
  4. #include <QWidget>
  5.  
  6. #include "testroot.h"
  7.  
  8. class CQp : public testroot
  9. {
  10.     Q_OBJECT
  11. public:
  12.     explicit CQp(QWidget *parent = 0);
  13.  
  14. signals:
  15.  
  16. public slots:
  17.  
  18. };
  19.  
  20. #endif // CQP_H

and when I try to compile, it complains that ‘QWidget’ is not a direct base of CQp. True. But I if make it a parent class to CQp explicitly, it complains that class CQp inherits QWidget from two places. Is there a way around that?

I guess I could make my non-abstract classes inherit QWidget separately, but that seems like ad-hoc solution. Am I missing something?

Anyhow, sorry for the vague question and long post, and thanks in advance for your time and dedication!

 Signature 

Joey Dumont

11 replies

June 22, 2011

loladiro loladiro
Lab Rat
596 posts

I guess your testroot inherits QWidget? In that case it has to have a similar constructor to your CQp class and you have to call that constructor.

June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

You guessed right, but I don’t understand what you mean.

 Signature 

Joey Dumont

June 22, 2011

loladiro loladiro
Lab Rat
596 posts

  1. class testroot : public QWidget
  2. {
  3. Q_OBJECT
  4. public:
  5.        testroot(QWidget *parent = 0) : QWidget(parent)
  6.        {}
  7. }
  8.  
  9. CQp::CQp(QWidget *parent) :
  10.     testroot(parent)
  11. {
  12. }

June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

Thanks!

Do you have any good reference book that talks about this kind of inheritance? My code now compiles, but I haven’t the slightest idea why. I read about inheritance before, but it’s always demonstrated in simple cases, and rarely with abstract classes.

Thanks, @loladiro!

 Signature 

Joey Dumont

June 22, 2011

peppe peppe
Ant Farmer
1028 posts
Joey Dumont wrote:
and when I try to compile, it complains that ‘QWidget’ is not a direct base of CQp. True. But I if make it a parent class to CQp explicitly, it complains that class CQp inherits QWidget from two places. Is there a way around that?

What the compiler is telling you is that from a constructor you can call only direct base constructors.

That is, if you have an inheritance chain like this

  1. A --> B --> C

(C inherits from B, B from A) then from C::C() you can call B::B(), but not A::A(), because it’s not a direct base for C.

The offending line is obviously the call to the QWidget ctor here, since “testcase” is a direct base for CQp, and QWidget is a non-direct base:

Joey Dumont wrote:
  1. #include "cqp.h"
  2.  
  3. CQp::CQp(QWidget *parent) :
  4.     QWidget(parent)
  5. {
  6. }
 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

And by using,

  1.  CQp::CQp(QWidget *parent):
  2. testroot(parent);
  3.  
  4. {
  5. }

what am I changing to the inheritance chain?

 Signature 

Joey Dumont

June 22, 2011

peppe peppe
Ant Farmer
1028 posts

You’re not changing the inheritance graph (which is defined by the class definition); that’s a call to a base constructor from your constructor. You’re now calling a costructor of a direct-base (allowed) instead of a non-direct base (forbidden).

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

June 22, 2011

loladiro loladiro
Lab Rat
596 posts

Nothing, but you are calling the constructor of your base class (which is the only constructor your are allowed to call in C++).

June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

Thanks for both your simultaneous answers!

Now, will I be able to instantiate the tests that are at the far end of the inheritance graph by using QWidget signals like show() and such? My guess is no, but if so my abstract classes organization scheme falls apart.

Any thoughts?

 Signature 

Joey Dumont

June 22, 2011

loladiro loladiro
Lab Rat
596 posts

Yes you will! Signals/Slots are inherited just like methods (because they are methods).

June 22, 2011

Joey Dumont Joey Dumont
Lab Rat
116 posts

Oh, I just got it. Thanks for your patience!

 Signature 

Joey Dumont

 
  ‹‹ which is best for parsing in Qt???      [Solved] QFileDialog::getOpenFileName breaks message boxes etc. ››

You must log in to post a reply. Not a member yet? Register here!