Zoeken…


Opmerkingen

In C ++ maakt, evenals in C, de C ++ compiler en het compilatieproces gebruik van de C preprocessor. Zoals gespecificeerd in de handleiding van GNU C Preprocessor, wordt een header-bestand als volgt gedefinieerd:

Een koptekstbestand is een bestand met C-verklaringen en macrodefinities (zie macro's) dat moet worden gedeeld tussen verschillende bronbestanden. U vraagt om het gebruik van een header-bestand in uw programma door het op te nemen, met de C preprocessing-richtlijn '#include'.

Koptekstbestanden hebben twee doelen.

  • Systeembestandsbestanden declareren de interfaces met delen van het besturingssysteem. U neemt ze op in uw programma om de definities en verklaringen te geven die u nodig hebt om systeemoproepen en bibliotheken op te roepen.
  • Uw eigen header-bestanden bevatten verklaringen voor interfaces tussen de bronbestanden van uw programma. Elke keer dat u een groep gerelateerde declaraties en macrodefinities hebt die alle of de meeste nodig zijn in verschillende bronbestanden, is het een goed idee om er een headerbestand voor te maken.

Voor de C-preprocessor zelf is een header-bestand echter niet anders dan een bronbestand.

Het schema voor kopteksten / bronbestanden is gewoon een krachtig en standaard congres dat door verschillende softwareprojecten wordt ingesteld om scheiding tussen interface en implementatie te bieden.

Hoewel het niet formeel wordt afgedwongen door de C ++ Standard zelf, wordt het volgen van de header / source file-conventie ten zeerste aanbevolen en is het in de praktijk al bijna alomtegenwoordig.

Merk op dat header-bestanden kunnen worden vervangen als een projectbestandstructuurconventie door de komende functie van modules, die nog moet worden overwogen voor opname in een toekomstige C ++ Standard vanaf het moment van schrijven (bijv. C ++ 20).

Basis voorbeeld

Het volgende voorbeeld zal een codeblok bevatten dat bedoeld is om te worden opgesplitst in verschillende bronbestanden, zoals aangegeven met // filename .

Bronbestanden

// my_function.h

/* Note how this header contains only a declaration of a function.
 * Header functions usually do not define implementations for declarations
 * unless code must be further processed at compile time, as in templates.
 */

/* Also, usually header files include preprocessor guards so that every header
 * is never included twice.
 *
 * The guard is implemented by checking if a header-file unique preprocessor
 * token is defined, and only including the header if it hasn't been included
 * once before.
 */
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

// global_value and my_function() will be
// recognized as the same constructs if this header is included by different files.
const int global_value = 42;
int my_function();

#endif // MY_FUNCTION_H

// my_function.cpp

/* Note how the corresponding source file for the header includes the interface  
 * defined in the header so that the compiler is aware of what the source file is 
 * implementing.
 *
 * In this case, the source file requires knowledge of the global constant
 * global_value only defined in my_function.h. Without inclusion of the header
 * file, this source file would not compile.
 */
#include "my_function.h" // or #include "my_function.hpp"
int my_function() {
  return global_value; // return 42;
}

Koptekstbestanden worden vervolgens opgenomen door andere bronbestanden die de functionaliteit willen gebruiken die is gedefinieerd door de koptekstinterface, maar geen kennis van de implementatie ervan vereist (dus vermindering van codekoppeling). Het volgende programma maakt gebruik van de kop my_function.h zoals hierboven gedefinieerd:

// main.cpp

#include <iostream>       // A C++ Standard Library header.
#include "my_function.h"  // A personal header

int main(int argc, char** argv) {
  std::cout << my_function() << std::endl;
  return 0;
}

Het compilatieproces

Omdat headerbestanden vaak deel uitmaken van een compilatieprocesworkflow, zal een typisch compilatieproces dat gebruik maakt van de header / source file-conventie meestal het volgende doen.

Ervan uitgaande dat het headerbestand en het broncodebestand zich al in dezelfde map bevinden, voert een programmeur de volgende opdrachten uit:

g++ -c my_function.cpp       # Compiles the source file my_function.cpp
                             # --> object file my_function.o

g++ main.cpp my_function.o   # Links the object file containing the 
                             # implementation of int my_function()
                             # to the compiled, object version of main.cpp
                             # and then produces the final executable a.out

Als alternatief, als men main.cpp naar een objectbestand wil compileren en vervolgens alleen objectbestanden als laatste stap aan elkaar wil koppelen:

g++ -c my_function.cpp
g++ -c main.cpp

g++ main.o my_function.o

Sjablonen in koptekstbestanden

Sjablonen vereisen compilatie tijdens het genereren van code: een sjabloonfunctie, bijvoorbeeld, zal effectief worden omgezet in meerdere afzonderlijke functies zodra een sjabloonfunctie wordt geparametreerd door gebruik in broncode.

Dit betekent dat sjabloonfunctie, lidfunctie en klassedefinities niet kunnen worden gedelegeerd naar een afzonderlijk broncodebestand, omdat elke code die een sjabloonconstructie gebruikt, kennis van de definitie vereist om in het algemeen afgeleide code te genereren.

Dus moet templated code, indien ingevoerd in headers, ook zijn definitie bevatten. Een voorbeeld hiervan is hieronder:

// templated_function.h

template <typename T>
T* null_T_pointer() {
  T* type_point = NULL; // or, alternatively, nullptr instead of NULL
                        // for C++11 or later
  return type_point;
} 


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow