Header files in C en C++ worden gebruikt voor informatie die op
verschillende plaatsen bekend moet zijn, zoals constanten,
functie-prototypes en class-definities. Een header file (.h) is iets
anders dan een implementatiefile (.cpp). Een implementatiefile maakt
de objecten, functies en variabelen van je programma. De header voorziet
de implementatie van informatie.
De rol van een header
Het is belangrijk om je te realiseren welke constructies in een header
thuishoren en welke niet. Hiervoor moet je eerst de rol van een header
begrijpen. Daarom dit lijstje met de belangrijkste redenen voor het gebruik
van een header file:
- Interface voor gebruikers van jouw bibliotheek
- Interface tussen jouw eigen implementatiefiles
- Concentreren van gegevens
Wat mag niet in een header staan ?
In het algemeen kun je zeggen dat constructies die geheugen alloceren
niet in een header moeten staan. Een header kan door verschillende
implementatiefiles worden gebruikt. Zou in de header een constructie
staan die geheugen nodig heeft, dan zou dat geheugen dus meerdere malen
worden aangevraagd en nog wel onder dezelfde naam ook. Daar maak je de
linker niet blij mee want die kan geen onderscheid maken tussen variabelen
met dezelfde naam.
Wat mag wel (of moet) in een header staan ?
- #define SAMPLES_PER_SECOND 44100
- short calculate_next_sample(double);
- extern double samplerate;
- class MidiEvent {...};
Let op: je mag een class slechts één keer definieren. Een
header file kan echter bij het compileren van een cpp-file meerdere keren
'included' worden, bijvoorbeeld via andere header files. Hoe kun je
voorkomen dat de inhoud van een header file meerdere keren wordt meegenomen
waardoor bijvoorbeeld classes meerdere keren gedefinieerd worden ?
Het antwoord staat bij de uitleg over de
preprocessor.
Wat staat er dan in de implementatie ?
In de implementatie (.cpp) vind je bijvoorbeeld het volgende:
- short calculate_next_sample(double freq) { return freq/SAMPLES_PER_SECOND; }
- double samplerate;
- const int temp = 5;
- unsigned char MidiEvent::get_velocity();
Let hier op als je meerdere sources gebruikt
Als je je programma verdeelt over meerder implementatiefiles (en dat is
al gauw zo) let dan op het volgende:
- Zorg dat er geen functies met dezelfde naam in meerdere sources
staan
- Hetzelfde voor globale variabelen
- Als je globale variabelen gebruikt, definieer die dan eenmalig in een
implementatiefile en declareer ze als extern in header files
- Als een .cpp file een functies uit een andere .cpp file wil aanroepen,
neem dan in een relevante header een prototype van de functie op
- Zorg dat er een .cpp file is waar een main() routine in staat