There are several different file extensions which are supported by some IDEs, typically those are ".cpp", ".h", ".hpp", ".c" etc.
You only need to be concerned with .cpp and .h at the moment.
Typically, you use .h (also known as header files) to
declare classes, functions, and sometimes variables. Notice, I said declare, not define. If I want to write a Radio class - in a header file - I would say that the Radio class (and all of its members) is/are something that can exist.
Let's also assume that I want my Radio class to have a member function named "toggle()", which turns the radio on if it's off, and off if it's on. It would look something like this:
radio.h
1 2 3 4 5 6 7 8 9 10 11 12
|
#ifndef _RADIO_H_/*ignore this line for now*/
#define _RADIO_H_/*ignore this line for now*/
class Radio {
public :
bool on;
Radio(); /*both the Radio default constructor and the toggle() function are declared, but have no body.*/
void toggle(); /*in order for them to do things, I need to give them a body, which is done in a separate .cpp file*/
};
#endif/*ignore this line for now*/
|
.cpp files, on the other hand, you would use to
define class methods, other functions and variables. In other words, now you're giving the previously defined things (that exist, but have no value or purpose) a value or a purpose.
I now want to give a body to both my Radio default constructor, and the Radio.toggle() function. Usually, the implementations (definitions and body functions) of a class go into a separate .cpp file by the same name.
radio.cpp
1 2 3 4 5 6 7 8 9
|
#include "radio.h"
Radio::Radio() {/*Default constructor now has a function body, in which I initialize the Radio.on member to false.*/
on = false;
}
void Radio::toggle() {/*toggle() function now has a body*/
on = !on;/*on is equal to not-on. If on is true, on will be false and vice versa*/
}
|
There are a few cases in which not every .h file will be accompanied by a .cpp file (this has to do with templates, so don't worry about that yet).
There may also very well be cases in which not every .cpp file is related to a .h file, such as in the case of possibly a main or "driver program".
When all your class members are defined, you can
#include
the .h in any other file that may need to know about your class and it's methods. This relationship between .h and .cpp files works as long as the linker can find an implementation of a class and its methods.
Another very important thing to know about header files, is that they need a so called "header guard"/"include guard". The header guard is important, because if you don't have a header guard, and happen to include the same header twice (or in a file which you include later on somewhere else), you'll get compilation errors pertaining to multiple inclusions (the same class/function/whatever already has been declared).
Header guards make sure that headers are only included once, and only for the first time they are included. There are several ways of doing this. One way of doing it is by using the non-standard
#pragma once
pre-processor directive. Here is an example of it's application:
1 2 3 4 5 6 7 8 9
|
#pragma once
class Radio {
public :
bool on;
Radio();
void toggle();
};
|
Another way of doing it would be to use a "macro guard" - to
#define
a reserved macro keyword. This is the method that I prefer:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#ifndef _RADIO_H_/*if _RADIO_H_ has not been defined*/
#define _RADIO_H_/*then define it*/
/*otherwise, if it has already been defined, all the code from here to the #endif does not get compiled, and as a result, does not get declared more than once*/
class Radio {
public :
bool on;
Radio();
void toggle();
};
#endif/*necessary for any #if. The #endif is at the end of the file, because if a definition already exists for _RADIO_H_, I don't want to include this class declaration again.*/
|
Just for the sake of completeness, this is how I would use my radio class in a "driver program":
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12
|
#include <iostream>
#include "radio.h"
int main(int argc, char* argv[]) {
Radio radio;
std::cout << "radio.on: " << radio.on << std::endl;
radio.toggle();
std::cout << "radio.on: " << radio.on << std::endl;
std::cin.get();
return 0;
}
|