Stuck trying to #include interdepenant headers

I have two classes and in each class I would like to have a pointer to an instance of the other.
But the compiler is complaining because I can't use one type until it is completely defined.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//header classa.h
class ClassA{
  public:
    ClassB *pB; 
    void testA();
} 
ClassA::ClassA(){}

//header classb.h
class ClassB{
  public:
    ClassA *pA; 
    void testB(); 
}
ClassB::ClassB(){}

// classa.cpp
void ClassA::testA(){
   pB->testB(); 
}

// classb.cpp
void ClassB::testB(){
   pA->testA(); 
}

No matter which header I include first the other class will be incomplete.
How do I resolve this?
Last edited on
You must forward declare ClassB.

1
2
3
4
5
class ClassB;

class ClassA {
    ClassB *pB;
};
Edit: After posting i worked it out to the point where it compiles correctly. Consequently I am changing the code to show the changes.
//-----------------------------------

Unfortunately I am lost in an include maze.
I am not certain where includes are supposed to go.

I have three classes, MainWindowII, State, Game.
Game needs a link to both MainWindowII and State.
State needs a link to game.
And MainWindowII needs a link to Game.

Here they are complete with the includes that I have been cutting and pasting all over.

Start with main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <QApplication>
#include "statemachine.h"
#include "game.h"
#include "mainwindowii.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindowII w;
    StateMachine *pState = new StateMachine();
    //Game *pGame = new Game(sm);
    Game *pGame = new Game();
    w.setGame(pGame);
//    sm->setGame(pGame);
    w.show();

    int retVal = a.exec();

    delete pGame;
    delete pState;

    return retVal;
}

MainWindowII.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef MAINWINDOWII_H
#define MAINWINDOWII_H

#include <QMainWindow>
#include <QLabel>
#include <QBoxLayout>
#include <QStyle>
#include <QDesktopWidget>
#include <QScreen>


class Game;
//class StateMachine;

namespace Ui {
class MainWindowII;
}

class MainWindowII : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindowII(QWidget *parent = nullptr);
    ~MainWindowII();

    void setGame(Game *g);
    Game *_pGame;                               // pointer to the game object
    QLabel *_pTitleLabel;                       // label to show the title - probably morph this to use as general purpose image display

private slots:
    void startNewGame();

    void on_actionNew_Game_triggered();


private:
    Ui::MainWindowII *ui;


    void initTitle();           // load the title bitmap
};

#endif // MAINWINDOWII_H

MainWindowII.cpp --> In order to limit the amount of posted code I'll show the header section only
1
2
3
4
5
#include "mainwindowii.h"
#include "ui_mainwindowii.h"
#include "game.h"
MainWindowII::MainWindowII(QWidget *parent) :

statemachine.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

#ifndef STATEMACHINE_H
#define STATEMACHINE_H
//#include "game.h"
class Game;

enum class State{
    Init,
    NewGame,
    Start_screen,
    Seating
};

class StateMachine
{
public:

    StateMachine(){}
    //StateMachine::StateMachine()
    //{
    //}

    ~StateMachine();

    void setGame(Game *g);
    //void setState(const State pState);
    //void stateEnter();
    //void stateExit();
private:
    //int count = 0;
    Game *_pGame;
    //State _currentState;
    //void onState_Init();
    //void onState_NewGame();
};

#endif // STATE_H

statemachine.cpp --- include header section only
1
2
#include "statemachine.h"
#include <QDebug> 

game.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef GAME_H
#define GAME_H

#include <QMainWindow>

//#include "statemachine.h"
class StateMachine;
//class MainWindowII;

class Game
{
private:
    QMainWindow *_pMainWindow;
    StateMachine *_pState;      // pointer to the state machine
public:
    Game(){}
//    Game(StateMachine *sm);

    void setStateMachine(StateMachine *sm);
    void setMainWindow(QMainWindow *mw);
    void init();
    void startNewGame();
};
/*Game::Game(StateMachine *sm)
{
    this->_pState = sm;
}
*/

#endif // GAME_H

game.cpp --- include header section only
1
2
3
#include <QDebug>
#include "game.h"

Obviously this is giving me lots of incomplete type errors.
Any help cleaning this up is appreciated.
(sorry to dump so much code)
Last edited on
I actually got it to work.
I backtracked and commented out everything and worked my way forward.
Unfortunately I don't feel like I have learned anything and it is just by virtue of the compiler complaining that i worked it out.
I am editing the previous to note post to note the now working code.
>You must forward declare ClassB.
and you must forward declare ClassA

here are some include rules
https://cplusplus.com/articles/Gw6AC542/
(ps: don't forget your include guards)


> Game *pGame = new Game();
Game pGame;
done
Topic archived. No new replies allowed.