Classes and header files

Oct 6, 2013 at 1:33am
closed account (ETAkoG1T)

1
2
3
4
5
6
7
8
9
10
// header1.h
class a {
public:
void func(b* item);
}
// header2.h
class b {
public:
void func(a* item);
}

I want to be able to use the a class in class b, and the b class in class a.
How can I make this work?
Last edited on Oct 6, 2013 at 1:46am
Oct 6, 2013 at 1:45am
Declare class b as forward.
You will also need to change line 4 to a pointer since a complete type is required.

1
2
3
4
5
6
// header1.h
class b;
class a {
public:
func(b * item);
}
Oct 6, 2013 at 1:52am
closed account (ETAkoG1T)
What if I need to use a class that is derived from a in class b?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// header1.h
class b;
class a {
public:
    void func(b* item);
}
class c : public a {
    void Execute();
}
// header2.h

// Add what here?
class b {
public:
    void func(c* item)
   {
        item->Execute();
   }
}


Last edited on Oct 6, 2013 at 2:13am
Oct 6, 2013 at 2:09am
Between lines 1 and 2, just add class b;, it won't affect the rest of your code except to make line 4 compile.
Oct 6, 2013 at 2:13am
closed account (ETAkoG1T)
I updated it, but that doesn't really matter anymore since AbstractionAnon already told me that. Now I want to do it with inherited classes.
Oct 6, 2013 at 2:28am
I don't really understand your question, what problem are you having with that code?
Oct 6, 2013 at 2:36am
closed account (ETAkoG1T)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef HEADER2_H_
#define HEADER2_H_

#include "header1.h"

class a;
class c;

class b {
public:
    void func(c* item)
   {
        item->Execute();
   }
};

#endif 


use of undefined type 'c'

Last edited on Oct 6, 2013 at 2:37am
Oct 6, 2013 at 3:26am
Why would you declare a type and then not define it?
What's in header1.h?
Last edited on Oct 6, 2013 at 3:27am
Oct 6, 2013 at 3:31am
Before you said that the definitions of a and c are in header1.h, but now you instead forward declare them and you show a compiler error about them not being defined? You're really not making sense now. You sure header1.h does NOT include header2.h?
Last edited on Oct 6, 2013 at 3:31am
Oct 6, 2013 at 4:02am
closed account (ETAkoG1T)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef HEADER1_H_
#define HEADER1_H_

#include "header2.h"
#include <iostream>

class b;
class a {
public:
    void func(b* item);
};

class c : public a {
public:
	void Execute() { std::cout << "Hello World"; }
};

#endif 
Oct 6, 2013 at 4:03am
You need to remove line 4.
Oct 6, 2013 at 4:04am
closed account (ETAkoG1T)
I just want to find out how I can tell the compiler that c is in header.1 so header.2 can use class c.
Oct 6, 2013 at 5:12am
I don't know what makes you think it would be unintuitive.


1
2
3
4
5
6
7
8
9
10
#ifndef _HEADER1_H_
#define _HEADER1_H_

class a {
public :
	a() {}
	void method() {/*...*/}
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
#ifndef _HEADER2_H_
#define _HEADER2_H_

#include "header1.h"

class b {
public :
	b() {}
	void method() {a object; object.method();}
};
#endif 
Last edited on Oct 6, 2013 at 5:13am
Oct 6, 2013 at 5:37am
closed account (ETAkoG1T)
Am I thinking wrong? This is supposed to be a finite state machine.

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
#ifndef MINER_H_
#define MINER_H_
#include "States.h"


class Miner
{
	State * CurrentState;
	int GoldCarried;
	int GoldInBank;
public:
	Miner() { CurrentState = Sleeping().instance(); }

	void update() 
	{
		if (CurrentState)
		{
			CurrentState->Execute(this);
		}
	}

	void ChangeState(State * NewState) {
		if (CurrentState && NewState)
		{
			CurrentState->Exit(this);
			CurrentState = NewState;
			CurrentState->Enter(this);
		}
	}

};

#endif 


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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef STATES_H_
#define STATES_H_

#include "Miner.h"
#include <iostream>
using namespace std;

class State
{
public:
	virtual ~State(){ };

	virtual void Enter(Miner* n)=0;

	virtual void Execute(Miner* n)=0;

	virtual void Exit(Miner* n)=0;
};


class Sleeping : public State
{
public:
	Sleeping() { };
	virtual void Enter(Miner* Unit) 
	{
		cout << "Going to sleep...\n";
	}
	virtual void Execute(Miner* Unit);

	virtual void Exit(Miner* Unit)
	{
		cout << "!What was that?!";
	}
	Sleeping * instance() { 
		static Sleeping sleep;
		return &sleep;
	}
};

class Working : public State
{
public:
	Working() { };
	virtual void Enter(Miner* Unit)
	{
		cout << "Looking forward to working\n";
	}
	virtual void Execute(Miner* Unit)
	{
		cout << "Working is making me tired\n";
		static int Work;
		Work++;
		if ( Work > 4 )
		{
			Work = 0;
			Unit->ChangeState(Sleeping().instance());
		}
	}

	virtual void Exit(Miner* Unit)
	{
		cout << "I'm exhausted\n";
	}

	Working * instance() 
	{
		static Working work;
		return &work;
	}
};


#endif 


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
#include "States.h"
#include "Miner.h"


void Sleeping::Execute(Miner* Unit) 
{
		cout << "ZZZZzzzZZZ...\n";
		static int sleepCounter;
		sleepCounter++;
		if ( sleepCounter > 2 )
		{
			sleepCounter = 0;
			Unit->ChangeState(Working().instance());
		}
}

void Working::Execute(Miner* Unit) 

{
		cout << "Working is making me tired\n";
		static int Work;
		Work++;
		if ( Work > 4 )
		{
			Work = 0;
			Unit->ChangeState(Sleeping().instance());
		}
	}


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
#include "States.h"
#include "Miner.h"


void Sleeping::Execute(Miner* Unit) 
{
		cout << "ZZZZzzzZZZ...\n";
		static int sleepCounter;
		sleepCounter++;
		if ( sleepCounter > 2 )
		{
			sleepCounter = 0;
			Unit->ChangeState(Working().instance());
		}
}

void Working::Execute(Miner* Unit) 

{
		cout << "Working is making me tired\n";
		static int Work;
		Work++;
		if ( Work > 4 )
		{
			Work = 0;
			Unit->ChangeState(Sleeping().instance());
		}
	}



1
2
3
4
5
6
7
8
9
10
11
12
#include "Miner.h"
#include "States.h"
#include <iostream>
int main()
{
	Miner Tom;
	for ( int i = 0; i < 10; i++ )
	{
		Tom.update();
	}
	cin.get();
}
Last edited on Oct 6, 2013 at 5:38am
Oct 6, 2013 at 6:31am
Do you get any errors there?

Generally, you can use:
class A; to forward declare a pointer only. If you want to use a method or access a member, you need to #include that class's header.

This is how I do it:
1
2
3
4
5
6
7
8
9
10
11
class B;
class A
{
    B* b;
public:
    void method(); // this will manipulate b, but we don't say that here;
};
class C : public A
{
    // ...
};

1
2
3
4
5
6
7
class C; // You don't need to know about class A here
class B;
{
    C* c;
pubic:
    void method();
}

1
2
3
4
5
6
7
#include "classB.h"
#include "classAC.h" // This is only place we need the full declaration of class A and C

void B::method()
{
    c->method();
}
Last edited on Oct 6, 2013 at 6:31am
Oct 6, 2013 at 11:23am
closed account (ETAkoG1T)
I need to use singleton classes for states. So I can't just declare it inside the class even if that would work. If you are interested to help me further you should take a look at the code.
Oct 6, 2013 at 5:09pm
You're including headers in each other - don't do that.
Oct 6, 2013 at 5:55pm
If you are interested to help me further you should take a look at the code.

If you are interested in being helped, you should pay attention to what is being said to you. You cannot define methods in the class (A) which require the full definition of another class (B) for which the full definition (of class B) is not available. The obvious solution is to move those method definitions outside of the class definition. One usually puts them into a source (.cpp) file. In that source file, one may #include whatever headers are necessary, because those headers will not be including each other. This also has the benefit of separating the interface (in the header file) from the implementation (in the source file.)

Oct 6, 2013 at 11:39pm
closed account (ETAkoG1T)
Atleast now I know why my c++ book insists on using a seperate file for declaring functions from the classes :)
Topic archived. No new replies allowed.