У меня есть повторяющиеся определения, хотя я использую защиту заголовков. [Дубликат]

Помимо всех (хорошо объясненных) ответов, не было упомянутых ниже, и я часто посещаю этот Q & amp; A.

В двух словах; MySQL думает, что вы хотите сделать математику в своей таблице / столбце и интерпретируете дефисы, такие как «электронная почта», как e минус mail.


Отказ от ответственности: Поэтому я думал, что добавлю это как ответ типа «FYI» для тех, кто совершенно не знаком с работой с базами данных, и которые могут не понимать уже описанные технические термины.

0
задан coinsyx 10 February 2014 в 12:54
поделиться

4 ответа

Вы определяете my_var один раз на единицу компиляции . Помните, что включение охранников выполняется на основе каждой единицы компиляции.

Чтобы исправить это, вы должны объявить my_var как extern в заголовке:

#ifndef _HEAD_H_
#define _HEAD_H_

extern int my_var;

#endif

и определяют его в одном из исходных файлов, используя

int my_var = 100;

. Тогда компоновщик видит только одно определение, и все будет хорошо.

2
ответ дан Bathsheba 27 August 2018 в 01:16
поделиться

Защита только предотвращает включение заголовка дважды в один и тот же блок компиляции.

Когда вы компилируете src1.o и src2.o, каждый из них будет содержать определение my_var. Когда вы связываете их для создания a.out, компилятор не может объединить эти определения (даже если они идентичны) и не работает.

Что вы хотите сделать, это объявить my_var как extern :

---- head.h ----

#ifndef _HEAD_H_
#define _HEAD_H_

extern int my_var;

#endif

---- my_var.c ----

#include "head.h"

int my_var = 100;

Затем скомпилируйте все исходные файлы:

g++ -c my_var.cpp -o my_var.o
g++ -c src1.cpp -o scr1.o
g++ -c src2.cpp -o src2.o
g++ -o a.out my_var.o src2.o src1.o

Таким образом, my_var будет объявлен в каждом файле, но будет определен только ] в my_var.o. Здесь важная разница. Попробуйте пропустить ссылку my_var.o, вы увидите, что компилятор должен сказать:)

1
ответ дан Maël Nison 27 August 2018 в 01:16
поделиться

ваша проблема сводится к пониманию классов хранения C ++; статический и внешний.

extern says: this variable is defined in a different file, this 
             is only a declaration
static says: this variable's lifetime is the program lifetime and
             restrict it's visibility to the current file. 



What happens in your case:
   - each file includes the variable declaration and definition `int my_var = 100;`,
     so both object scr1.o and scr2.o will contain the variable definition. When
     linking them, the linker cannot solve the ambiguity and throws an error.
   - adding the extern qualifier and defining the variable in one of the files 
     solves this problem: in one source it'll be an external unresolved at compile
     time, symbol and the other will contain the actual symbol.

Что касается второй части вашего вопроса; почему добавление статики, похоже, помогает компоновщику. Посмотрите, что я только что сказал о статическом классе хранения: в основном каждый объект будет иметь свою собственную копию переменной - не то же самое!

0
ответ дан Pandrei 27 August 2018 в 01:16
поделиться

Измените заголовок следующим образом

#ifndef _HEAD_H_
#define _HEAD_H_

extern int my_var;

#endif

И, например, добавьте строку в модуль с основным

#include "head.h"
int my_var = 100;
int main() { return 0; }

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

3
ответ дан Vlad from Moscow 27 August 2018 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: