[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
    @
    #include "Base.h"

    Base::Base(QWidget *parent) : QMainWindow(parent)
    {
    sub = new Sub();
    }
    @

    Base.h
    @
    #ifndef BASE_H
    #define BASE_H

    #include <QMainWindow>
    #include "Sub.h"

    class Base : public QMainWindow
    {
    Q_OBJECT

    public:
    Base(QWidget *parent = 0);

    private:
    Sub *sub;
    };

    #endif // BASE_H
    @

    Sub.cpp
    @
    #include "Sub.h"

    Sub::Sub() { }

    void Sub::foobar(Base *id)
    {
    // Do something with id or call a method in class Base
    }
    @

    Sub.h
    @
    #ifndef SUB_H
    #define SUB_H

    #include <QObject>
    #include "Base.h"

    class Sub : public QObject
    {
    Q_OBJECT

    public:
    Sub();
    void foobar(Base *id); // Here is the error: Base has not been declared
    };

    #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



  • You can use a "forward declaration":http://en.wikipedia.org/wiki/Forward_declaration.
    @
    #ifndef SUB_H
    #define SUB_H

    #include <QObject>
    // no need to include Base.h

    class Base; // forward declaration of class Base

    class Sub : public QObject
    {
    Q_OBJECT

    public:
    Sub();
    void foobar(Base *id);
    };
    @



  • 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


  • Moderators

    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 :)



  • 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


Log in to reply
 

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