once
(и другие включают охрану ) не будут препятствовать множественным определениям.once
предотвращает включение заголовка дважды одним файлом cpp ( единица перевода ).Если несколько блоков перевода включают в себя один и тот же заголовок, у всех них будет своя копия всего в этом заголовке.Это включает в себя определенные переменные и функции.Все эти модули перевода скомпилированы отдельно, поэтому любой прогон компилятора не знает, что другой прогон уже включил заголовок и создал объектный файл, который имеет свою собственную копию того же материала.
The Linker,однако, нужно взять эти несколько единиц перевода и объединить их в одну программу.И он находит все дублирование.Вместо того, чтобы пытаться разобраться, что на самом деле хочет программист, он сдается и просит программиста уточнить.
Ответ Songyuanyao дает одно решение этой проблемы: объявите переменную с помощью extern
вместо ее определения взаголовок, а затем определить переменную в одной единице перевода.Это позволяет нескольким переводчикам использовать одну переменную.Вы можете сделать то же самое с определением функции с ключевым словом inline
.
Иногда, , но не на этот раз , вы хотите, чтобы каждая единица перевода имела свою собственную переменную.В этом случае
#pragma once
class EventManager;
namespace GlobalSys {
namespace {
EventManager * eventManager;
}
}
Анонимное пространство имен ограничивает связь eventManager
с одной единицей перевода, поэтому eventManager
каждой единицы перевода не конфликтуют.