Udostępnij za pośrednictwem


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ów
  • constexpr Obiektów
  • typedef Obiektów
  • static 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ż

Podstawowe pojęcia