Here. I've slapped together a little crash course for you, just so everyone is on the same page.
.h and .cpp file extensions
Header files (.h) typically contain class declarations and prototypes for functions, variables and other identifiers.
This means they typically don't contain any actual execution code - but they can, and sometimes, under very special circumstances, have to.
Source code files (.cpp) contain the implementations (function body) of previously declared things (like functions, variables, whatever).
Therefore, it's save to say that USUALLY a .cpp file has an accompanying .h file (usually by the same name), and vice versa.
If another file needs to know about something you've declared elsewhere, you include the header file that contains the needed definitions.
"include guards/macro guards"
If you include a header file multiple times in a project in different files, you'll get compilation errors regarding name clashes.
Consider the following scenario:
class Baby needs to know about class Person.
class Adult also needs to know about class Person.
Baby and Adult would include the necessary Person declarations.
The second time the Person declarations show up in the compilation process, the compiler complains because the Person declarations already exist.
This is why it becomes necessary to use so called "include/macro guards", which ensure that the declarations they encapsulate only ever show up once in the compilation process.
One way of doing this is by using the preprocessor #ifndef (if no definition) control structure like so.
1 2 3 4 5 6 7 8
|
#ifndef _PERSON_H_//(if there's no definition present for _PERSON_H_)
#define _PERSON_H_//(then define it)
class Person {
/**/
};
#endif//(end of the #if control structure)
|
#include<> vs #include""
Typically, you use
#include <>
for headers that are located in the compiler/IDE include directory (the standard files that come with your compiler/IDE).
You use
#include ""
for local project files (files which you've created, and added to the project).
cyclic dependancies
Sometimes, class Foo needs to know about class Bar, and class Bar needs to know about class Foo.
In this case, one can use a forward declaration/class prototype, like so:
foo.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#ifndef _FOO_H_
#define _FOO_H_
#include "bar.h"
class Bar;//prototype for Bar
class Foo {
public :
Foo() {/**/}
int foo;
Bar* bar;
};
#endif
|
bar.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
#ifndef _BAR_H_
#define _BAR_H_
#include "foo.h"
class Foo;//prototype for Foo
class Bar {
public :
Bar() {/**/}
int bar;
Foo* foo;
};
#endif
|