Jednostki translacji i połączenie
W programie C++ symbol, na przykład zmienna lub nazwa funkcji, można zadeklarować dowolną liczbę razy w zakresie. Można go jednak zdefiniować tylko raz. Ta reguła to "Jedna reguła definicji" (ODR). Deklaracja wprowadza (lub ponownie wprowadza) nazwę do programu wraz z wystarczającą ilością informacji, aby później skojarzyć nazwę z definicją. Definicja wprowadza nazwę i udostępnia wszystkie informacje potrzebne do jej utworzenia. Jeśli nazwa reprezentuje zmienną, definicja jawnie tworzy magazyn i inicjuje go. Definicja funkcji składa się z podpisu oraz treści funkcji. Definicja klasy składa się z nazwy klasy, po której następuje blok zawierający listę wszystkich składowych klasy. (Jednostki funkcji członkowskich mogą być opcjonalnie definiowane oddzielnie w innym pliku).
W poniższym przykładzie przedstawiono niektóre deklaracje:
int i;
int f(int x);
class C;
W poniższym przykładzie przedstawiono niektóre definicje:
int i{42};
int f(int x){ return x * i; }
class C {
public:
void DoSomething();
};
Program składa się z co najmniej jednej jednostki tłumaczenia. Jednostka tłumaczenia składa się z pliku implementacji i wszystkich nagłówków, które zawiera bezpośrednio lub pośrednio. Pliki implementacji zwykle mają rozszerzenie .cpp
pliku lub .cxx
. Pliki nagłówkowe zwykle mają rozszerzenie .h
lub .hpp
. Każda jednostka tłumaczenia jest kompilowana niezależnie przez kompilator. Po zakończeniu kompilacji konsolidator scala skompilowane jednostki tłumaczenia w jeden program. Naruszenia reguły ODR są zwykle wyświetlane jako błędy konsolidatora. Błędy konsolidatora występują, gdy ta sama nazwa jest zdefiniowana w więcej niż jednej jednostce tłumaczenia.
Ogólnie rzecz biorąc, najlepszym sposobem na uwidocznienie zmiennej w wielu plikach jest zadeklarowanie go w pliku nagłówkowym. Następnie dodaj dyrektywę #include
w każdym .cpp
pliku, który wymaga deklaracji. Dodając osłony dołączania wokół zawartości nagłówka, upewnij się, że nazwy, które deklaruje nagłówek, są deklarowane tylko raz dla każdej jednostki tłumaczenia. Zdefiniuj nazwę tylko w jednym pliku implementacji.
W języku C++20 moduły są wprowadzane jako ulepszona alternatywa dla plików nagłówkowych.
W niektórych przypadkach może być konieczne zadeklarowanie zmiennej globalnej lub klasy w .cpp
pliku. W takich przypadkach potrzebny jest sposób na określenie kompilatora i konsolidatora, jakiego rodzaju połączenie ma nazwa. Typ połączenia określa, czy nazwa obiektu jest widoczna tylko w jednym pliku, czy we wszystkich plikach. Pojęcie powiązania dotyczy tylko nazw globalnych. Pojęcie powiązania nie ma zastosowania do nazw zadeklarowanych w zakresie. Zakres jest określany przez zestaw otaczających nawiasów klamrowych, takich jak w definicjach funkcji lub klas.
Połączenie zewnętrzne a wewnętrzne
Bezpłatna funkcja jest funkcją zdefiniowaną w zakresie globalnym lub przestrzeni nazw. Zmienne globalne inne niż const i funkcje wolne domyślnie mają połączenie zewnętrzne; są one widoczne z dowolnej jednostki tłumaczenia w programie. Żaden inny obiekt globalny nie może mieć tej nazwy. Symbol z wewnętrznym połączeniem lub brakiem połączenia jest widoczny tylko w jednostce tłumaczenia, w której jest zadeklarowany. Jeśli nazwa ma połączenie wewnętrzne, ta sama nazwa może istnieć w innej jednostce tłumaczenia. Zmienne zadeklarowane w definicjach klas lub ciałach funkcji nie mają powiązania.
Możesz wymusić, aby nazwa globalna miała wewnętrzne powiązania, jawnie deklarując ją jako static
. To słowo kluczowe ogranicza widoczność do tej samej jednostki tłumaczenia, w której jest zadeklarowana. W tym kontekście static
oznacza coś innego niż w przypadku zastosowania do zmiennych lokalnych.
Domyślnie następujące obiekty mają połączenie wewnętrzne:
const
Obiektówconstexpr
Obiektówtypedef
Obiektówstatic
obiekty w zakresie przestrzeni nazw
Aby nadać obiektowi połączenie zewnętrzne, zadeklaruj const
go jako extern
i przypisz mu wartość:
extern const int value = 42;
W celu uzyskania więcej informacji, zobacz następujący temat: extern
.
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla