Header Guards

Pages: 12
I've completley confused myself and no nothings working. I'd love any help I can get thanks.

I'll post all 3 header file

1)
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
 #ifndef RANDOMCLASSHEADER_H_INCLUDED
#define RANDOMCLASSHEADER_H_INCLUDED
#include "human.h"
#include "staff.h"







class Customer : public Human
{

    Customer();

 public:
    Customer(char name[], char gender[], int phone, char pcode[], float dob);

    void setName(char name[]);
    char* getName();

    void setGender(char get[]);
    char* getGender();

    void setPhone(int phone);
    int getPhone();

    void setPcode(char pcode[]);
    char* getPcode();

    void setDob(float dob);
    float getDob();


 private:
    char cust_name[50];
    char cust_gender[50];
    int cust_phone;
    char cust_pcode[50];
    float cust_dob;
};
#endif // RANDOMCLASSHEADER_H_INCLUDED
#endif // STAFF_H_INCLUDED 


2)
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
 #ifndef RANDOMCLASSHEADER_H_INCLUDED
#define RANDOMCLASSHEADER_H_INCLUDED
#ifndef HUMAN_H_INCLUDED
#define HUMAN_H_INCLUDED
#include "cust.h"
#include "staff.h"





class Human
{

    Human();
    public:
    Human(int identity);
    void setID(int identity);
    int getID();

    private:
    int human_identity;
};
#endif // HUMAN_H_INCLUDED
#endif // STAFF_H_INCLUDED 


3)
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
#ifndef RANDOMCLASSHEADER_H_INCLUDED
#define RANDOMCLASSHEADER_H_INCLUDED
#ifndef STAFF_H_INCLUDED
#define STAFF_H_INCLUDED

class Staff
{

    Staff();

 public:
    Staff(char rank[], char annualWage[], float hours);

    void setRank(char rank[]);
    char* getRank();

    void setWage(char annualWage[]);
    char* getWage();

    void setHours(float hours);
    float getHours();



 private:
    char staff_rank[50];
    char staff_wage[50];
    float staff_hours;
};
#endif // RANDOMCLASSHEADER_H_INCLUDED
#endif // STAFF_H_INCLUDED
 


Thanks for any help.
Only have one, unique "header guard" in each file. At the moment, your defining RANDOMCLASSHEADER_H_INCLUDED in every file, so for the other two the preprocessor will just skip over the rest of that file until the appropriate #endif is reached.
Can I just delete all the header guards and end ifs?

edit: I also don't know where "RANDOMCLASSHEADER_H_INCLUDED" came from after I changed the name of the header files, maybe I just copied them over.
Last edited on
I'm guessing you did copy them over.

And no, as it stands you can't just delete them, because they're all referencing each other (ie, cust calls human calls cust). If you just deleted all the header guards, you'd end up with multiple declarations.
Last edited on
Each header file needs one and only one include guard. For each of them, you need a unique symbol (the word after #define ). Also notice that #ifndef (if not defined) and #endif are a pair. The first file you posted has one #ifndef and two #endif s. As I showed you in the other thread, the basic structure of a header file is this:

1
2
3
4
5
6
7
8
#ifndef FOO
#define FOO

class Foo {
    // ...
};

#endif 

If the class inherits or uses a type declared in a different header file, you need to #include it. The #include directive simply copies and pastes text. An include guard prevents a header file from being copied twice into the same translation unit (which is the .cpp file plus all its #include s).

If, however, the class uses a pointer or reference to a type declared elsewhere, all you need is a forward declaration, so the file will look like this:

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

class Bar; // forward declaration

class Foo {
    // ...
};

#endif 
Last edited on
I understand the include bit, but what on earth do the "guards" guard against?

so say my class was called Human then I'd need
1
2
3
4
5
6
7
8
9
#ifndef Human
#define Human


class Human
{
};

#endif 
I understand the include bit, but what on earth do the "guards" guard against?


They guard against the same cpp file including the same header more than once. See examples and explanation here:

http://www.cplusplus.com/forum/articles/10627/#msg49679

so say my class was called Human then I'd need


No, you'd need to pick a unique identifier. Human is not unique because your class is named Human. This would be a problem.

I would do this:

1
2
3
4
5
6
7
8
#ifndef HUMAN_H_INCLUDED  // must be unique!
#define HUMAN_H_INCLUDED

class Human
{
};

#endif 
I've changed all that

1) is STAFF_H_INCLUDED
2) is HUMAN_H_INCLUDED
3) is CUSTOMER_H_INCLUDED

and I've #included "human.h" on my customer.h file as it's using inheritance and on my main. Do I need to #include human.h on my customer.cpp?

getting this error atm:
1
2
3
4
5
6
7
/home/rej3kt/Desktop/C++ Class/custclass/human.h||In constructor ‘Customer::Customer()’:|
/home/rej3kt/Desktop/C++ Class/custclass/human.h|8|error: ‘Human::Human()’ is private|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|6|error: within this context|
/home/rej3kt/Desktop/C++ Class/custclass/human.h||In constructor ‘Customer::Customer(char*, char*, int, char*, float)’:|
/home/rej3kt/Desktop/C++ Class/custclass/human.h|8|error: ‘Human::Human()’ is private|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|9|error: within this context|
||=== Build finished: 4 errors, 0 warnings ===|
Move the Human() in the second file down to below the public: identifier.
Started compiling then threw this error message back:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp||In function ‘int main()’:|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|11|warning: unused variable ‘cust_name’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|12|warning: unused variable ‘cust_gender’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|13|warning: unused variable ‘cust_phone’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|14|warning: unused variable ‘cust_pcode’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|15|warning: unused variable ‘cust_dob’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|16|warning: unused variable ‘number’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|17|warning: unused variable ‘username’|
/home/rej3kt/Desktop/C++ Class/custclass/main.cpp|18|warning: unused variable ‘selection’|
obj/Debug/cust.o||In function `Customer':|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|6|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|6|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|9|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|9|undefined reference to `Human::Human()'|
||=== Build finished: 4 errors, 8 warnings ===| 


So it's not seeing where I've defined my variables in my customer class :S
No it saying two things:

1. you have a lot of unused variable - this is just a warning or information. You probably are going to use these variables.

2. the human::human() constructor function does not have a body ( that is to say you have not defined it).



Also - To continue what Pax has started - you should make the customer() and staff() constructors public as well and define (give them bodies) as well.
sorry just realised I'd commented out most of my main.cpp to test the inheritance.

1
2
3
4
5
6
obj/Debug/cust.o||In function `Customer':|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|6|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|6|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|9|undefined reference to `Human::Human()'|
/home/rej3kt/Desktop/C++ Class/custclass/cust.cpp|9|undefined reference to `Human::Human()'|
||=== Build finished: 4 errors, 0 warnings ===| 


This is in my cust.cpp file so not quite sure why it can't find the class.

The error is in this beginning part of the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "cust.h"
#include "staff.h"
#include "human.h"
#include <string.h>

Customer::Customer()
{
}
Customer::Customer(char name[], char gender[], int phone, char pcode[], float dob)
{
    strcpy(cust_name, name);
    strcpy(cust_gender, gender);
    cust_phone = phone;
    strcpy(cust_pcode, pcode);
    cust_dob = dob;


}


I've changed those constructors to public (thanks for the help on that)
The linker is saying that during the customer constructor, - when it tried to link to the human base class constructor Human::Human() function it couldn't find it.

(all derived classes have to make a call to it's immediate base class constructor first - either implicitly or explicitly)
Last edited on
I don't understand which part of that is trying to link to my human class other than #include "human.h"
Your customer class inherits from the Human class, so the Constructor of the Customer Class (Customer::Customer()) calls the constructor of the Human class (Human::Human()), but can not find it. Do you have a human.cpp file?
Nah, I don't have a human.cpp file sorry. So I need to make a constructor in a .cpp for :
1
2
3
4
Human::Human()

{
}


to declare a function for
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 #ifndef HUMAN_H_INCLUDED  // must be unique!
#define HUMAN_H_INCLUDED


class Human
{


    public:
    Human();
    Human(int identity);
    void setID(int identity);
    int getID();

    private:
    int human_identity;
};

#endif 


Am I right?
Last edited on
Yes... you could do it by just putting a {} before the semi-colon on the same line to avoid making another file.

I think once you've done that, you'll encounter linker errors with other undefined functions though. So perhaps make them all just empty for now?
Those functions are so short they should be inlined (defined inside class declaration). It's as simple as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Human {
public:
    Human()
    :human_identity(0) { }

    Human(int id)
    :human_identity(id) { }

    void setID(int id) { human_identity = id; }
    int getID() { return human_identity; }

private:
    int human_identity;
};

Notice I gave a default value to human_identity. You should always initialize your variables.
Thanks alot mate I've got it working now, time to test if the inheritance part is work. What do you reckon the best way to do this would be? I was thinking like this:

1
2
3
4
cout << "Enter your identity number: " <<endl
cin << human_identity;

cout << c1.getID();


This would store the data in human identity then it'd get accessed by the customer class. Hopefully.
Does that make any difference to my program Fillipe?
Pages: 12