Когда использовать extern в C++?
Я читаю книгу "Think in C++", и в ней только что была введена декларация extern
. Например:
extern int x;
extern float y;
Я думаю, что понимаю значение (декларация без определения), но меня интересует, когда это оказывается полезным.
Может кто-нибудь привести пример?
4 ответ(ов)
Это становится полезным, когда у вас есть глобальные переменные. Вы объявляете существование глобальных переменных в заголовочном файле, чтобы каждый исходный файл, который включает этот заголовок, знал об их существовании, но вам нужно «определить» переменную только один раз в одном из ваших исходных файлов.
Для уточнения, использование extern int x;
указывает компилятору, что объект типа int
с именем x
существует где-то. Компилятору не нужно знать, где именно она существует, нужно лишь знать тип и имя, чтобы понимать, как это использовать. После компиляции всех исходных файлов компоновщик разрешит все ссылки на x
к одному определению, которое он найдет в одном из скомпилированных исходных файлов. Чтобы это сработало, определение переменной x
должно иметь так называемую «внешнюю связь», что в основном означает, что она должна быть объявлена вне функции (в так называемой «области видимости файла») и без ключевого слова static
.
Заголовочный файл:
#ifndef HEADER_H
#define HEADER_H
// любой исходный файл, который включает этот заголовок, сможет использовать "global_x"
extern int global_x;
void print_global_x();
#endif
Исходный файл 1:
#include "header.h"
// так как global_x все еще нужно определить где-то,
// мы определяем его (например) в этом исходном файле
int global_x;
int main()
{
//устанавливаем global_x здесь:
global_x = 5;
print_global_x();
}
Исходный файл 2:
#include <iostream>
#include "header.h"
void print_global_x()
{
//выводим global_x здесь:
std::cout << global_x << std::endl;
}
Когда вам нужно поделиться переменной между несколькими модулями, полезно определить её в одном модуле, а в других использовать ключевое слово extern
.
Например:
в файле file1.cpp
:
int global_int = 1;
в файле file2.cpp
:
extern int global_int;
// Внутри какой-либо функции
cout << "global_int = " << global_int;
Таким образом, extern
позволяет вам использовать переменную global_int
, объявленную в file1.cpp
, в file2.cpp
, что удобно для организации кода и управления общими данными.
Всё дело в связывании.
Предыдущие ответы удачно объяснили, как работает extern
.
Но я хочу добавить важный момент.
Вы спрашиваете о extern
в C++, а не в C, и я не понимаю, почему никто не упомянул случай, когда extern
используется с const
в C++.
В C++ переменная const
по умолчанию имеет внутреннюю привязку (в отличие от C).
Таким образом, этот сценарий приведет к ошибке связывания:
Исходник 1:
const int global = 255; // неверный способ определения глобальной константы в C++
Исходник 2:
extern const int global; // объявление
Правильный вариант будет выглядеть так:
Исходник 1:
extern const int global = 255; // определение глобальной константы в C++
Исходник 2:
extern const int global; // объявление
Помните, что в C++ для глобальных const
переменных необходимо явно указывать extern
в их определении, чтобы избежать проблем со связкой!
Это полезно, когда вам нужно создать глобальную переменную. Вы определяете глобальные переменные в одном исходном файле, а в заголовочном файле объявляете их с помощью ключевого слова extern
, чтобы любой файл, который включает этот заголовочный файл, имел доступ к одной и той же глобальной переменной.
Что такое Правило трёх?
Разница между const int*, const int * const и int * const?
Имеют ли круглые скобки после имени типа значение при использовании new?
Как удалить элемент из std::vector<> по индексу?
`unsigned int` против `size_t`: когда и что использовать?