Jakie rzeczy absolutnie nigdy nie powinny być zawarte w pliku nagłówkowym?
Jeśli na przykład pracuję z udokumentowanym standardowym formatem przemysłowym, który ma wiele stałych, czy dobrą praktyką jest ich definiowanie w pliku nagłówkowym (jeśli piszę parser dla tego formatu)?
Jakie funkcje powinny przejść do pliku nagłówka?
Jakie funkcje nie powinny?
Odpowiedzi:
Co umieścić w nagłówkach:
#include
dyrektyw potrzebnych do kompilacji nagłówka, gdy nagłówek jest zawarty w pliku źródłowym.Co nie należy do nagłówka:
#include
dyrektywy. Te nieodpłatne obejmują powodowanie ponownej kompilacji rzeczy, które nie wymagają ponownej kompilacji i mogą czasami sprawić, że system nie będzie mógł kompilować. Nie rób#include
pliku w nagłówku, jeśli sam nagłówek nie potrzebuje tego innego pliku nagłówka.#include
, które mogą ulec zmianie lub są zbyt duże. Te wbudowane funkcje powinny mieć niewielki lub żaden wentylator, a jeśli mają wentylator, powinien być zlokalizowany na elementy zdefiniowane w nagłówku.Co stanowi minimalny zestaw
#include
instrukcji?To okazuje się nietrywialne pytanie. Definicja TL; DR: Plik nagłówka musi zawierać pliki nagłówkowe, które bezpośrednio definiują każdy z typów bezpośrednio użytych lub które bezpośrednio deklarują każdą z funkcji użytych w danym pliku nagłówkowym, ale nie mogą zawierać niczego innego. Wskaźnik lub typ referencyjny C ++ nie kwalifikuje się jako bezpośrednie użycie; preferowane są odniesienia do przodu.
Jest miejsce na nieuzasadnioną
#include
dyrektywę, która odbywa się w zautomatyzowanym teście. Dla każdego pliku nagłówka w pakiecie oprogramowania automatycznie generuję, a następnie kompiluję:Kompilacja powinna być czysta (tzn. Wolna od ostrzeżeń i błędów). Ostrzeżenia lub błędy dotyczące niekompletnych lub nieznanych typów oznaczają, że w testowanym pliku nagłówkowym brakuje niektórych
#include
dyrektyw i / lub brakujących deklaracji forward. Uwaga: tylko dlatego, że wynik testu nie oznacza, że zestaw#include
dyrektyw jest wystarczający, a co dopiero minimalny.źródło
Oprócz tego, co już zostało powiedziane.
Pliki H powinny zawsze zawierać:
Pliki H nigdy nie powinny zawierać:
static
.(Powiedziałbym również, że nigdy nie ma powodu, aby używać niestałych zmiennych globalnych / zewnętrznych, ale jest to dyskusja na inny post).
źródło
Prawdopodobnie nigdy nie powiedziałbym nigdy, ale instrukcje, które podczas analizowania generują dane i kod, nie powinny znajdować się w pliku .h.
Makra, wbudowane funkcje i szablony mogą wyglądać jak dane lub kod, ale nie generują kodu podczas analizowania, ale zamiast tego, gdy są używane. Te elementy często muszą być używane w więcej niż jednym .c lub .cpp, więc należą do .h.
Moim zdaniem plik nagłówkowy powinien mieć minimalny praktyczny interfejs do odpowiedniego pliku .c lub .cpp. Interfejs może zawierać #define, class, typedef, definicje struktur, prototypy funkcji i mniej preferowane zewnętrzne definicje zmiennych globalnych. Jeśli jednak deklaracja jest używana tylko w jednym pliku źródłowym, prawdopodobnie powinna zostać wykluczona z .h i zamiast tego powinna być zawarta w pliku źródłowym.
Niektórzy mogą się nie zgadzać, ale moje osobiste kryteria dla plików .h są takie, że # zawierają wszystkie inne pliki .h, które muszą być w stanie skompilować. W niektórych przypadkach może to być wiele plików, więc mamy kilka skutecznych metod zmniejszania zależności zewnętrznych, takich jak deklaracje przekazywania do klas, które pozwalają nam używać wskaźników do obiektów klasy bez uwzględnienia dużego drzewa plików dołączanych.
źródło
Plik nagłówkowy powinien mieć następującą organizację:
Pliki nagłówkowe nigdy nie powinny zawierać definicji obiektów, a jedynie definicje typów i deklaracje obiektów.
źródło
Instrukcje generujące dane i kod podczas ich analizowania nie powinny znajdować się w
.h
pliku. Jeśli chodzi o mój punkt widzenia, plik nagłówkowy powinien mieć minimalny praktyczny interfejs do odpowiedniego.c
lub.cpp
.źródło