Прежде чем говорить о вопросе, лучше узнать термин единица перевода , , программа и некоторые базовый Понятия C ++ (на самом деле связывание является одним из них в общем) точно. Вы также должны будете знать, что такое scope .
Я выделю некоторые ключевые моменты, особенно пропавших без вести в предыдущих ответах.
Связывание является свойством имени , которое вводится декларацией . Разные имена могут обозначать одну и ту же сущность (обычно объект или функцию). Поэтому говорить о связи сущности, как правило, бессмысленно, если только вы не уверены, что сущность будет ссылаться только на уникальное имя из некоторых конкретных объявлений (обычно одного объявления).
Обратите внимание, что объект является сущностью, а переменная - нет. Говоря о связывании переменной, на самом деле речь идет об имени обозначенной сущности (которое вводится посредством конкретного объявления). Связь имени указана в одном из трех: нет связи, внутренняя связь или внешняя связь.
Различные единицы перевода могут совместно использовать одну и ту же декларацию путем включения заголовочного / исходного файла (да, это формулировка стандарта). Таким образом, вы можете ссылаться на одно и то же имя в разных единицах перевода. Если объявленное имя имеет внешнюю связь, идентичность сущности, на которую ссылается имя, также является общей. Если объявленное имя имеет внутреннюю связь, одно и то же имя в разных единицах перевода обозначает разные сущности, но вы можете ссылаться на сущность в разных областях одной и той же единицы перевода. Если имя не имеет связи, вы просто не можете ссылаться на сущность из других областей.
(Упс ... Я обнаружил, что набрал несколько повторений стандартную формулировку ...)
Есть также некоторые другие запутанные моменты, которые не охватываются языковой спецификацией.
- Видимость (имени). Это также свойство объявленного имени, но со значением, отличным от связи .
- Видимость (побочного эффекта) . Это не относится к этой теме.
- Видимость (символа). Это понятие может использоваться в реальных реализациях . В таких реализациях символ с определенной видимостью в объектном (двоичном) коде обычно является целью, отображаемой из определения сущности, чьи имена имеют такую же конкретную связь в исходном (C ++) коде. Тем не менее, это обычно не гарантируется один на один. Например, символ в образе динамической библиотеки может быть указан только для внутреннего использования в этом изображении из исходного кода (связан с некоторыми расширениями, как правило,
__attribute__
или __declspec
) или параметров компилятора, и изображение не является всей программой или объектный файл, переведенный из модуля перевода, поэтому ни одна стандартная концепция не может точно его описать. Поскольку символ не является нормативным термином в C ++, это всего лишь подробности реализации, даже несмотря на то, что соответствующие расширения диалектов могли быть широко приняты.
- Доступность. В C ++ это обычно свойство членов класса или базовых классов , что опять-таки является другим понятием, не связанным с темой.
- Global. В C ++ «глобальный» относится к глобальному пространству имен или глобальной области имен. Последнее примерно эквивалентно области файлов на языке Си. Как в C, так и в C ++, связь не имеет ничего общего с областью действия, хотя область (например, связь) также тесно связана с идентификатором (в C) или именем (в C ++), введенным некоторым объявлением.
Правило связывания области имен const
переменная является чем-то особенным (и особенно отличается от объекта const
, объявленного в области файлов на языке C, который также имеет концепцию связывания идентификаторов). Поскольку ODR обеспечивается C ++, важно сохранить не более одного определения одной и той же переменной или функции, встречающейся во всей программе, за исключением inline
functions . Если такого специального правила для const
нет, то самое простое объявление переменной const
с инициализаторами (например, = xxx
) в заголовке или в исходном файле (часто это «файл заголовка»), включаемое несколькими единицами перевода (или включение одной единицы перевода более одного раза (хотя и редко) в программу нарушит ODR, что делает невозможным использование переменной const
, поскольку замена некоторых объектоподобных макросов невозможна.