Header Guards

Pages: 12
Oct 27, 2010 at 10:42am
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.
Oct 27, 2010 at 11:04am
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.
Oct 27, 2010 at 11:18am
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 Oct 27, 2010 at 11:35am
Oct 27, 2010 at 1:02pm
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 Oct 27, 2010 at 1:03pm
Oct 27, 2010 at 2:16pm
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 Oct 27, 2010 at 2:18pm
Oct 27, 2010 at 4:19pm
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 
Oct 27, 2010 at 4:38pm
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 
Oct 27, 2010 at 5:08pm
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 ===|
Oct 27, 2010 at 6:21pm
Move the Human() in the second file down to below the public: identifier.
Oct 27, 2010 at 6:37pm
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
Oct 27, 2010 at 6:57pm
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.
Oct 27, 2010 at 7:18pm
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)
Oct 27, 2010 at 7:36pm
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 Oct 27, 2010 at 7:39pm
Oct 27, 2010 at 8:46pm
I don't understand which part of that is trying to link to my human class other than #include "human.h"
Oct 28, 2010 at 8:10am
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?
Oct 28, 2010 at 8:45am
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 Oct 28, 2010 at 10:08am
Oct 28, 2010 at 11:22am
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?
Oct 28, 2010 at 1:43pm
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.
Oct 28, 2010 at 2:34pm
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.
Oct 28, 2010 at 2:42pm
Does that make any difference to my program Fillipe?
Pages: 12