Stuck trying to #include interdepenant headers

Feb 28, 2022 at 3:27am
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 Feb 28, 2022 at 3:27am
Feb 28, 2022 at 3:31am
You must forward declare ClassB.

1
2
3
4
5
class ClassB;

class ClassA {
    ClassB *pB;
};
Feb 28, 2022 at 4:11am
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 Feb 28, 2022 at 6:31am
Feb 28, 2022 at 6:25am
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.
Feb 28, 2022 at 3:26pm
>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.