C++
Sidhuvudfiler
Sök…
Anmärkningar
I C ++, som i C, använder C ++ kompilatorn och kompilationsprocessen C-förbehandlaren. Som anges i GNU C Preprocessor-manualen definieras en rubrikfil som följande:
En rubrikfil är en fil som innehåller C-deklarationer och makrodefinitioner (se makron) som ska delas mellan flera källfiler. Du begär användning av en rubrikfil i ditt program genom att inkludera den, med C-förbehandlingsdirektivet '#include'.
Headerfiler tjänar två syften.
- Systemhuvudfiler deklarerar gränssnitten till delar av operativsystemet. Du inkluderar dem i ditt program för att tillhandahålla de definitioner och deklarationer du behöver för att åberopa systemsamtal och bibliotek.
- Dina egna sidfiler innehåller deklarationer för gränssnitt mellan programmets källfiler. Varje gång du har en grupp relaterade deklarationer och makrodefinitioner som alla eller de flesta behövs i flera olika källfiler är det en bra idé att skapa en rubrikfil för dem.
Men för C-förbehandlaren själv är en huvudfil inte annorlunda än en källfil.
Organisationsschemat för rubrik / källfil är helt enkelt ett starkt hållet och standardkonvention som ställs in av olika programvaruprojekt för att ge skillnad mellan gränssnitt och implementering.
Även om den inte formellt upprätthålls av C ++ -standarden själv, är det mycket starkt att följa konventionen om rubrik / källfil, och i praktiken är den redan nästan allestädes närvarande.
Observera att rubrikfiler kan ersättas som en projektfilstrukturkonvention av den kommande funktionen i moduler, som fortfarande ska övervägas för att inkluderas i en framtida C ++ -standard från skrivande tid (t.ex. C ++ 20).
Grundläggande exempel
Följande exempel innehåller ett kodblock som är avsett att delas upp i flera källfiler, som betecknas med // filename
.
Källfiler
// 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;
}
Headerfiler inkluderas sedan av andra källfiler som vill använda den funktionalitet som definieras av rubrikgränssnittet, men kräver inte kunskap om dess implementering (alltså minska kodkopplingen). Följande program använder rubriken my_function.h
enligt definitionen ovan:
// 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;
}
Samlingsprocessen
Eftersom rubrikfiler ofta är en del av ett arbetsflöde för en sammanställningsprocess, kommer en typisk sammanställningsprocess som använder huvud- / källfilskonventionen vanligtvis att göra följande.
Om man antar att rubrikfilen och källkodfilen redan finns i samma katalog, skulle en programmerare utföra följande kommandon:
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
Alternativt, om man vill sammanställa main.cpp
till en objektfil först och sedan länka endast objektfiler tillsammans som det sista steget:
g++ -c my_function.cpp
g++ -c main.cpp
g++ main.o my_function.o
Mallar i rubrikfiler
Mallar kräver sammanställning av tidskodgenerering: en mallad funktion, till exempel, förvandlas effektivt till flera distinkta funktioner när en mallformad funktion är parametrerad genom användning i källkod.
Detta innebär att mallfunktion, medlemsfunktion och klassdefinitioner inte kan delegeras till en separat källkodfil, eftersom någon kod som kommer att använda någon formad konstruktion kräver kunskap om dess definition för att generellt generera någon derivatkod.
Således måste den mallade koden, om de läggs i rubriker, också innehålla sin definition. Ett exempel på detta är nedan:
// 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;
}