Passing an object to a function in other class

Hello, I wrote a simple code of two objects-"Human" and "Orc", and in each one a function that makes them attack each other.

In the "Orc" class I get an error-

error: 'Human' has not been declared

although I declared it.

Here is the code:

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
#ifndef ORC_H
#define ORC_H
#include <iostream>
#include <string>
#include "Human.h"

using namespace std;


class Orc
{
    public:
        Orc();
        void decHP(int dmg);
        bool isDead();
        void attack(Human *h); //The error is for that line
        virtual ~Orc();

    protected:

    private:
        int power=60;
        int hp=120;
        int attSp=1;
};

#endif // ORC_H
Last edited on
The compiler doesn't known what a "Human" is. You can forward declare it, and that's enough at that stage.

Only put the minimum amound of information in a header file. So all those #includes can go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef ORC_H
#define ORC_H

class Human;

class Orc
{
    public:
        Orc();
        void decHP(int dmg);
        bool isDead();
        void attack(Human *h); //The error is for that line
        virtual ~Orc();

    protected:

    private:
        int power=60;
        int hp=120;
        int attSp=1;
};

#endif // ORC_H 
Last edited on
Thanks, but I think I wasn't clear enough.

The class "Human" already exists in another file.

I don't know if it helps, but here is the code for "Human":

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
#ifndef HUMAN_H
#define HUMAN_H
#include <iostream>
#include <string>
#include "Orc.h"

using namespace std;


class Human
{
    public:
        Human();
        void decHP(int dmg);
        bool isDead();
        void attack(Orc *o);
        virtual ~Human();

    protected:

    private:
        int power=30;
        int hp=100;
        int attSp=2;
};

#endif // HUMAN_H


Thanks again!
Here's what human.h looks like to the compiler:

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
#ifndef HUMAN_H
#define HUMAN_H
#include <iostream>
#include <string>

#ifndef ORC_H
#define ORC_H
#include <iostream>
#include <string>

#ifndef HUMAN_H
#endif // HUMAN_H

using namespace std;


class Orc
{
    public:
        Orc();
        void decHP(int dmg);
        bool isDead();
        void attack(Human *h); //The error is for that line
        virtual ~Orc();

    protected:

    private:
        int power=60;
        int hp=120;
        int attSp=1;
};

#endif // ORC_H


using namespace std;


class Human
{
    public:
        Human();
        void decHP(int dmg);
        bool isDead();
        void attack(Orc *o);
        virtual ~Human();

    protected:

    private:
        int power=30;
        int hp=100;
        int attSp=2;
};

#endif // 


See how it has a use of human before human is defined? You've got a circular dependency. Either Orc or Human will be defined first, but it cannot be defined unless the other one has already been defined. As such, you need a forward declaration.
Last edited on
Thanks, but I think I wasn't clear enough.
I'm not sure what exactly you don't understand.

The class "Human" already exists in another file.
True, but class Human uses class Orc, and Orc uses Human, but they cannot simultaneously include each other. And that's where the problem began.

The trick is as I described. For the purposes of the declaring Orc, the compiler doesn't need to know exactly what Human is. To know that the parameter is a pointer to a class is sufficient because pretty much all pointers to a class are the same size.

However, in the orc.cpp file, you must use:
1
2
#include "orc.hpp"
#include "human.hpp" 

This is because, to generate the code for Orc, it needs to see human.hpp. Note, that this is different from the declaration.

I noticed you ignored other changes I made to that header file. You really ought to consider them.
Last edited on
I didn't get it at first, but now I understand. Thanks alot both of you really helped me!!

I noticed you ignored other changes I made to that header file. You really ought to consider them.
I added them to my code, thanks for that too!

Just for knowledge, how do I know which file is readed first by the compiler?
Last edited on

Just for knowledge, how do I know which file is readed first by the compiler?


The pre-processor goes through each *.cpp file, replacing every #include <somefile.h> with a copy-paste of the contents of "somefile.h" (paying attention to #ifdef directives it encounters)

Then, the compiler gets it. So for any given cpp file, start at the top, read downwards, and see what order the #include files are in.

Remember that those #include files themselves #include other file.

In summary; the compiler sees (and only knows about) one file at time. It never sees the header files; it gets one file with the header files copy-pasted in place of every #include.
Last edited on
The pre-processor goes through each *.cpp file, replacing every #include <somefile.h> with a copy-paste of the contents of "somefile.h" (paying attention to #ifdef directives it encounters)

Then, the compiler gets it. So for any given cpp file, start at the top, read downwards, and see what order the #include files are in.

Remember that those #include files themselves #include other file.

In summary; the compiler sees (and only knows about) one file at time. It never sees the header files; it gets one file with the header files copy-pasted in place of every #include.


Great explanation, thanks!
Topic archived. No new replies allowed.