Czytam „Think in C ++” i właśnie wprowadziłem extern
deklarację. Na przykład:
extern int x;
extern float y;
Myślę, że rozumiem znaczenie (deklaracja bez definicji), ale zastanawiam się, kiedy okaże się przydatne.
Czy ktoś może podać przykład?
Czytam „Think in C ++” i właśnie wprowadziłem extern
deklarację. Na przykład:
extern int x;
extern float y;
Myślę, że rozumiem znaczenie (deklaracja bez definicji), ale zastanawiam się, kiedy okaże się przydatne.
Czy ktoś może podać przykład?
Odpowiedzi:
Jest to przydatne, gdy masz zmienne globalne. W nagłówku deklarujesz istnienie zmiennych globalnych, tak aby każdy plik źródłowy zawierający nagłówek wiedział o nim, ale wystarczy „zdefiniować” go tylko raz w jednym ze swoich plików źródłowych.
Aby to wyjaśnić, użycie extern int x;
informuje kompilator, że obiekt typu o int
nazwie x
jest gdzieś istnieje . Nie jest zadaniem kompilatora wiedzieć, gdzie on istnieje, wystarczy znać typ i nazwę, aby wiedzieć, jak go używać. Po skompilowaniu wszystkich plików źródłowych konsolidator rozwiąże wszystkie odwołania x
do jednej definicji, którą znajdzie w jednym ze skompilowanych plików źródłowych. Aby zadziałało, definicja x
zmiennej musi mieć tak zwane „powiązanie zewnętrzne”, co w zasadzie oznacza, że należy ją zadeklarować poza funkcją (w tak zwanym „zakresie plików”) i bez static
słowa kluczowego.
#ifndef HEADER_H
#define HEADER_H
// any source file that includes this will be able to use "global_x"
extern int global_x;
void print_global_x();
#endif
#include "header.h"
// since global_x still needs to be defined somewhere,
// we define it (for example) in this source file
int global_x;
int main()
{
//set global_x here:
global_x = 5;
print_global_x();
}
#include <iostream>
#include "header.h"
void print_global_x()
{
//print global_x here:
std::cout << global_x << std::endl;
}
Jest to przydatne, gdy udostępniasz zmienną między kilkoma modułami. Zdefiniuj go w jednym module, a w innych użyj zewnętrznego.
Na przykład:
w pliku1.cpp:
int global_int = 1;
w pliku2.cpp:
extern int global_int;
//in some function
cout << "global_int = " << global_int;
global_int
w grę wchodzą przestrzenie nazw, jest w globalnej przestrzeni nazw, gdybym używał jej w pliku file2.cpp w jakiejś sekcji przestrzeni nazw, to musiałbym ją poprawnie zakreślić? tj.namespace XYZ{ void foo(){ ::global_int++ } };
abc.h
, istnieje duża szansa, że zostanie zdefiniowana abc.cpp
. Dobre IDE zawsze pomoże, ale dobrze zorganizowany kod jest zawsze lepszym rozwiązaniem.
extern
pliku2.cpp nadal można uzyskać dostęp do global_int
po dołączeniu. dlaczego muszę to mieć?
Chodzi o połączenie .
Poprzednie odpowiedzi dostarczyły dobrych wyjaśnień na temat extern
.
Ale chcę dodać ważną kwestię.
Pytasz extern
w C ++, a nie w C i nie wiem, dlaczego nie ma odpowiedzi na temat przypadku, gdy extern
jest const
w C ++.
W C ++ const
zmienna ma domyślnie wewnętrzne powiązanie (nie tak jak C).
Więc ten scenariusz doprowadzi do błędu połączenia :
Źródło 1:
const int global = 255; //wrong way to make a definition of global const variable in C++
Źródło 2:
extern const int global; //declaration
Musi być tak:
Źródło 1:
extern const int global = 255; //a definition of global const variable in C++
Źródło 2:
extern const int global; //declaration
extern
definicji? Możesz to zrobić, drukując wartość global
w źródle 2.
extern
jest pominięta const int global = 255;
.
Jest to przydatne, gdy chcesz mieć zmienną globalną. Definiujesz zmienne globalne w jakimś pliku źródłowym i deklarujesz je jako zewnętrzne w pliku nagłówkowym, aby każdy plik zawierający ten plik nagłówkowy zobaczył tę samą zmienną globalną.
extern
Kilkakrotnie musiałem podać definicję . Narzędzia Microsoft spowodowały błąd łącza dla brakujących symboli, gdy tabele w innym pliku źródłowym zostały zdefiniowane. Problem polegał na tym, że tabela była,const
a kompilator C ++ promował jąstatic
w jednostce tłumaczeniowej. Zobacz na przykładariatab.cpp
ikalynatab.cpp
.