Почему нестатическая переменная не может находиться в заголовочном файле? - PullRequest
5 голосов
/ 21 октября 2011

Взять например:

// myheader.h
static int myStaticVar = 0;
// If we remove 'static' the compiler will throw linker error.

void DoStuff();

// and myheader.cpp, and main.cpp;  etc

Вот как я бы это объяснил:

Статические переменные не имеют внешней связи, и когда мы компилируем без «статического» мы «включаем» статическую переменную (которая глобальный здесь) в каждом файле, который создает дубликаты и компоновщик будет выдает ошибку, так как множественное объявление не допускается.

Есть ли лучший способ объяснить это? Благодаря.

PS: мы предполагаем, что в заголовочном файле есть статические переменные (не говоря о членах)?

Ответы [ 3 ]

10 голосов
/ 21 октября 2011

Почему нестатическая переменная не может находиться в заголовочном файле?

Поскольку оно нарушает Одно правило определения (ODR) .
Когда вы включаете заголовочный файл, содержащий нестатическую переменную, объявлениепеременной вставляется в каждый исходный файл, где он включен.Таким образом, в итоге у вас будет более одного определения переменной в одном Единице перевода , это нарушит ODR и, следовательно, компоновщик выдаст вам ошибки при связывании.

Как объяснить статические переменные, объявленные в заголовочных файлах?

Когда вы объявляете статическую переменную в заголовочном файле, копия переменной создается в каждой Единица перевода , где включен заголовочный файл.

Объявление статической переменной в заголовочном файле не даст вам многократных ошибок определения, но это не приведет к вашей цели иметь глобальную переменную, значение которой является общим для всех файлов, которые к ней обращаются.

ВыМожет показаться, что, поскольку вы используете глобальную статическую переменную, ее значение будет сохраняться в разных файлах, но, как упоминалось выше, у каждого модуля перевода есть своя копия переменной, и она не достигает того, что, по вашему мнению, вы получаете.

Предполагается ли наличие в заголовочном файле статических переменных (не говоря уже о членах)?

Нет, никогда!

Как объявлять и определять глобальные переменные?

Вам необходимо использовать ключевое слово extern.

Добавить объявление extern переменной в заголовочный файл.Заголовок должен быть включен в один исходный файл, который определяет переменную, и во все исходные файлы, которые ссылаются на переменную. Только один исходный файл должен определить переменную.Также только один заголовочный файл должен объявлять переменную.

filename.h

extern int gVariable;  /* Declaration */ 

file1.cpp

#include "filename.h"  

/* Definition */ 
int gVariable = 37;    

void doSomething(void) 
{ 
    return gVariable++; 
} 

file2.cpp

#include "filename.h" 
#include <stdio.h>  
void doSomethingWithGlobal(void) 
{     
    printf("Global variable: %d\n", gVariable++); 
} 
1 голос
/ 21 октября 2011

Сначала прочитайте этот ответ на аналогичный вопрос.

Чтобы дополнить ответ, основанный на вашем вопросе, вот что:

Когда вы #include файл(любой файл, .h files - это общее соглашение), это почти просто копирование и вставка в ваш код .Если у вас есть нестатическая переменная в заголовочном файле, и вы включаете ее в два исходных файла, переменная вставляется в оба исходных файла , и вы получаете ошибку ссылки, как я объяснил в ответе Iсказал вам прочитать выше.

Если вы хотите совместно использовать глобальную переменную во многих исходных файлах, вы должны сделать следующее:

В только один ваших исходных файлов:

type global_var = default_value;

В заголовочном файле:

extern type global_var;

Таким образом, все исходные файлы увидят, что где-то в группе исходных файлов будет global_var.Только один из исходных файлов фактически содержит эту переменную, и при связывании все исходные файлы будут ссылаться на этот один экземпляр global_var

0 голосов
/ 21 октября 2011

Файл заголовка (.h) сообщает вам (объявляет), что будет делать файл определения (.cpp).

Для метафоры - файл заголовка похож на сообщение многим друзьям, что высобираюсь что-то сделать, но в действительности ты будешь делать это один раз.

...