January 3, 2013

NeedDeen NeedDeen
Lab Rat
10 posts

[SOLVED] Clean way to access base class from sub class

 

Hi

I know, this is a sort of lack of skill, but I wonder if there is a “clean” way to solve it (Maybe the Meta Object System ?). I have a class called Base. I create an other class called Sub and want to access a method in Base from Sub (Give the class Base als parameter results in a compiler error):

Base.cpp

  1. #include "Base.h"
  2.  
  3. Base::Base(QWidget *parent) : QMainWindow(parent)
  4. {
  5.  sub = new Sub();
  6. }

Base.h

  1. #ifndef BASE_H
  2. #define BASE_H
  3.  
  4. #include <QMainWindow>
  5. #include "Sub.h"
  6.  
  7. class Base : public QMainWindow
  8. {
  9.   Q_OBJECT
  10.  
  11.  public:
  12.   Base(QWidget *parent = 0);
  13.  
  14.  private:
  15.   Sub *sub;
  16. };
  17.  
  18. #endif // BASE_H

Sub.cpp

  1. #include "Sub.h"
  2.  
  3. Sub::Sub() { }
  4.  
  5. void Sub::foobar(Base *id)
  6. {
  7.   // Do something with id or call a method in class Base
  8. }

Sub.h

  1. #ifndef SUB_H
  2. #define SUB_H
  3.  
  4. #include <QObject>
  5. #include "Base.h"
  6.  
  7. class Sub : public QObject
  8. {
  9.   Q_OBJECT
  10.  
  11.  public:
  12.   Sub();
  13.   void foobar(Base *id); // Here is the error: Base has not been declared
  14. };
  15.  
  16. #endif // SUB_H

I know this is a lack of skill but I never had this problem because I always worked with consokle application or non-base methods

4 replies

January 3, 2013

Lukas Geyer Lukas Geyer
Lab Rat
2074 posts

You can use a forward declaration [en.wikipedia.org].

  1. #ifndef SUB_H
  2. #define SUB_H
  3.  
  4. #include <QObject>
  5. // no need to include Base.h
  6.  
  7. class Base; // forward declaration of class Base
  8.  
  9. class Sub : public QObject
  10. {
  11.   Q_OBJECT
  12.  
  13.  public:
  14.   Sub();
  15.   void foobar(Base *id);
  16. };

January 3, 2013

NeedDeen NeedDeen
Lab Rat
10 posts

Okay, I have 2 questions

1.) Let’s say I add a method called “bar” to the class Base and want to access this method from the class Sub, how should I do it ? My plan is to use modules -> A module controlls the GUI and call another module. When this module has finished, it should call another method in the GUI class (For example a TCP socket has a new package and updates the gui).
2.) I read that to use class <Classname> instead of #include results in a faster compilation – is this true ?

Thank you very much

January 4, 2013

Chris Kawa Chris Kawa
Dinosaur Breeder
1042 posts

1) You should review your design. Such circular dependencies are a pain to maintain.
The way you could do that is you could call a SomeModule::foo() method and when it finishes is would emit a signal: emit bar(); In your gui you connect to that signal some slot and do your other stuff there.
This is beneficial for few reasons: the other module doesn’t have to know anything about the gui and thus the circular include problem vanishes. The other is you could potentially do it asynchronously – the foo() method could return immediately and do some lenghty stuff in another thread without blocking the ui.

2) This is called forward declaration: in your bar.h file you “pre-declare” that there is somewhere a class called Foo, but don’t actually declare its layout. This allows you to use eg. Foo* as a member or funcion param. Than you include “foo.h” with the actual class declaration in your bar.cpp file. This way if the bar.h is included in many files it wont actually include foo.h multiple times and thus reduces compilation times. The idea is that you should keep your include section in the .h files to a minimum and forward declare whatever you can. This reduces the number of times the same headers are processed and greatly reduces compile times in large projects.
Edit: so basically what wiki that Lukas linked says :)

January 4, 2013

NeedDeen NeedDeen
Lab Rat
10 posts

Wow, thank you for this great information – it works like a charm and will simplify my future work a lot. The signal/slot design is very useful (Qt rocks), now I can emit a signal when a TCP socket has a new signal ;)

Thank you and have a nice weekend

 
  ‹‹ [Solved] Unhandled exception occurring inside my ’try’-block      [Solved] Is there a way to decide on the address model used for compilation of Qt ››

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