→ Что такое namespace c. Классы и пространства имен. Определение пространства имен

Что такое namespace c. Классы и пространства имен. Определение пространства имен

Поможет.
Путь к поддержке пространств имен в PHP был тернистым. Но к счастью она была добавлена к языку в версии PHP 5.3, и структура PHP кода значительно улучшилась с тех пор. Но как именно нам их использовать?

Что такое пространства имен?

«Не забывайте обратный слеш, когда Вы храните имя пространства имен в виде строки!»

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

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

Пространства имен, помогут! Вы можете объявить одни и те же функцию, класс, интерфейс и определить константу в отдельных пространствах имен, не получая фатальных ошибок. По своей сути, пространство имен не более чем иерархически маркированные блоки кода содержащие обычный PHP код.

Вы используете их!

Важно понимать, что Вы косвенно используете пространства имен; Начиная с PHP 5.3, все определения, которые еще не объявлены в определенных пользователем пространствах имен, подпадают под глобальное пространство имен.

Глобальное пространство имен также хранит все внутренние определения PHP, такие как mysqli_connect() , и класс Exception . Поскольку глобальное пространство имен не имеет уникального идентифицирующего названия, его наиболее часто называют глобальное пространство .

Обратите внимание что использование пространства имен не является обязательным.
Ваш PHP скрипт будет прекрасно работать без них, и такое поведение не очень скоро изменится.

Определение пространства имен

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

Пространства имен объявляются с помощью зарезервированного слова namespace . Пространства имен подчиняются тем же правилам, что и другие идентификаторы в PHP. Таким образом, пространство имен должно начинаться с буквы или символа подчеркивания с последующим любым количеством букв, цифр или символов подчеркивания .

Если Вы хотите определить блок кода в глобальное пространство, можно использовать ключевое слово namespace , не добавляя имени.

Вы можете использовать несколько пространств имен в одном файле.

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

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

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

Подпространства имен

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

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

PHP использует обратный слэш, в качестве разделителя пространства имен.

Интересный факт: в RFC , чтобы решить, какой разделитель пространства имен следует использовать, рассматривался вариант использования смайлика.

// myproject/database/connection.php Вы можете использовать столько вложенных пространств имен, сколько хотите.

Определение подпространства имен с вложенными блоками кода не поддерживается. Следующий пример будет возвращать фатальную ошибку: «Объявления пространств имен не могут быть вложенными (Namespace declarations cannot be nested)».

Вызов кода из пространства имен

Если Вы хотите, создать новый экземпляр объекта, вызвать функцию или использовать константы из разных пространств имен, Вы используете обратный слэш. Существует три типа определений имени пространства имен:
  • Неполное имя (Unqualified name)
  • Полное имя (Qualified name)
  • Абсолютное имя (Fully qualified name)

Неполное имя

Это имя класса, функции или константы, не включающее в себя ссылку к какому бы то ни было пространству имён. Для тех, кто только начинает работать с пространством имен, это привычная точка зрения.

Полное имя

Так мы получаем доступ к иерархии подпространства имен; разделяется обратным слэшем.

Пример ниже возвратит фатальную ошибку: «Fatal error: Class "MyProject\Database\MyProject\FileAccess\Input" not found», потому что MyProject\FileAccess\Input не имеет отношения к пространству имен в котором Вы находитесь.

Абсолютное имя

Полные и неполные имена используются по отношению к пространству имен в котором Вы находитесь в настоящее время. Они могут быть использованы только для определения доступа на этом уровне или нырять глубже в иерархию пространства имен.

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

Нам не обязательно использовать полное имя для внутренних функций PHP. Неполные имена для функций и констант будут определяться в глобальном пространстве имен, если они не определены в текущем пространстве имен.

Зная это, мы можем теперь перегружать внутренние функции PHP, при этом имея возможность вызвать первоначальную функцию (или константу).

"; }

Динамические вызовы

PHP - динамический язык программирования; так что Вы можете применять этот функционал для вызова кода из пространства имён. Это, по существу тоже, что использование динамического имени класса или подключение динамического файла используя переменную для хранения его имени. Разделитель имен PHP использует те же метасимволы в строках. Не забывайте про обратный слеш, когда Вы храните имя пространства имен в виде строки!

Ключевое слово namespace

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

Константа __NAMESPACE__

Так же как ключевое слово self не может быть использовано для определения имени текущего класса, также и ключевое слово namespace не может использоваться для текущего пространства имен. Поэтому мы используем константу __NAMESPACE__

Эта константа является весьма полезной в начале изучения пространства имен; также она очень полезна при отладке. Так как это строка, она может быть использована в сочетании с динамическими вызовами кода, рассмотренные выше.

Импорт или создание псевдонима имени

не обязательно использовать в пространствах имен

Важная особенность пространств имен в PHP - это возможность ссылаться на внешнее абсолютное имя по псевдониму , или импортирование .

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

Use as

Как это использовать

Абсолютное имя может быть привязаны к более короткому неполному имени, так что вам не придется писать его абсолютное имя каждый раз, когда Вы хотите его использовать. Создание псевдонима или импорт должны происходить в родительском пространстве имен или в глобальном. Попытка сделать это в рамках метода или функции является недопустимым синтаксисом (invalid syntax).

Альтернативой, является возможность присвоения псевдонима с другим именем

Вы также можете импортировать такие глобальные классы, как Exception. При импорте, вам не придется писать его абсолютное имя.

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

Хотя есть поддержка динамического вызова пространства имен, динамический импорт не поддерживается.

Вывод

Пространства имен используются, чтобы избежать конфликта определений и ввести больше гибкости и организации в программный код. Помните, что Вы не обязаны использовать пространства имен; это функция используется в сочетании с объектно-ориентированным подходом. Надеюсь, Вы рассмотрите возможность поднятия Вашего (будущего) PHP проекта на новый уровень за счет использования пространства имен.

Аннотация: В данном разделе описывается использование и декларация пространств имен. Даются основные характеристики RDF, XML-Data, Document Content Description (DCD), Schema for Object-Oriented XML (SOX), Document Definition Markup Language (DDML, ранее известный как XSchema).

Ранее мы описали некоторые недостатки определений DTD , они связаны:

  1. синтаксис этих определений отличается от синтаксиса XML (конкретно, используется так называемая расширенная форма Бэкуса-Наура , Extended Backus Naur Form );
  2. эти определения недостаточно выразительны;
  3. так как каждый пользователь может создавать свои собственные теги, то вполне вероятна ситуация когда для обозначения различных вещей люди будут пользоваться одними и теми же именами элементов. Даже если значения элементов одинаковы, их возможное содержание может изменяться в зависимости от определения. Таким образом, нам необходим способ, позволяющий определять конкретные виды использования элемента, особенно, если в одном документе мы смешиваем различные виды словарей. Для решения проблемы консорциум W3C выпустил спецификацию, называемую XML Namespaces (пространством имен XML), позволяющую определить контекст элемента в пространстве имен.
  4. существуют ситуации, когда необходимо скомбинировать документы XML из разных источников, соответствующих различным определениям DTD . Например, такая ситуация возникает при описании большого объема информации, если отдельных DTD недостаточно для охвата всего объема или они трудны для понимания. Возникает она и в системах электронной коммерции при попытках объединить данные вашего делового партнера с вашими. Так же может возникнуть ситуация когда необходимо просто добавить свои настройки к уже существующей DTD для того чтобы обмениваться некоторой информацией в стандартном формате. К сожалению, рекомендация XML не предоставляет способа совмещения нескольким DTD в одном документе без их модификации или создания нового DTD (используя внешние ссылки).

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

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

  • Лучше организовывать словари для решения сложных проблем;
  • Сохранять сильную типизацию данных при преобразованиях в XML и из него;
  • Более точно и гибко описывать словари, чем это было возможно в случае DTD ;
  • Читать правила словаря на языке XML, осуществляя доступ к его определениям без усложнения анализатора.

Смешение словарей

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

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

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

Пространства имен

Пространства имен способны помочь пользователю в двух очень важных случаях. С их помощью можно:

  • совмещать документы из двух или более источников, не теряя при этом уверенности, что программа различит, из какого источника взят тот или иной элемент или атрибут;
  • по возможности разрешит агенту пользователя доступ к дальнейшему материалу, такому как определение типа документа (DTD ) или другому описанию элементов и атрибутов.

Пространство имен представляет собой совокупность некоторых величин или характеристик, которые могут быть использованы в XML-документах как имена элементов или атрибутов. Пространства имен в XML определяются унифицированным идентификатором ресурса URI (в качестве URI можно использовать адрес DTD на вашем сервере). Он позволяет каждому пространству имен быть уникальным.

Итак, для того чтобы эффективно использовать пространства имен в документе, комбинирующем элементы из различных источников, нам надо определить:

  • Ссылку на URI, описывающий использование элемента.
  • Псевдоним, позволяющий понять, из какого пространства имен взят наш элемент. Этот псевдоним имеет форму префикса элемента (например, если псевдонимом для неясного элемента Book является слово catalog , то, элемент будет называться ).

Использование и декларация пространств имен

Декларация пространства имен

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

Поскольку необходимо, чтобы, встретив декларацию пространства имен каждый мог распознать ее, для него зарезервируем специальное слово. В соответствии с рекомендацией пространств имен, это слово xmlns . Значением атрибута является идентификатор URI , определяющий используемое пространство имен. Часто это адрес URL определения DTD , но так должно быть не всегда. Префикс и идентификатор пространства имен определяются атрибутом xmlns следующим образом:

Как видите, префикс ntb только что определен, но его уже можно использовать в имени ntb: notebook . В дальнейшем имена тегов и атрибутов, которые мы хотим отнести к пространству имен http://some.firm.com/2003/ntbml , снабжаются префиксом ntb, например:

Горелово

Кроме того, в одном теге могут встречаться сразу несколько пространств имен. Ниже приводится пример смешения нескольких пространств имен:

Элемент book взят из пространства имен catalog , а атрибут ISBN - из order .

Имя вместе с префиксом, например

называется расширенным, уточненным или квалифицированным именем (OName. Qualified Name ). Часть имени, записанная после двоеточия, называется локальной частью (local part ) имени.

Номенклатура названий Web-ресурсов может запутать. Универсальный указатель ресурса ( Uniform Resource Locator , URL ) указывает на ресурс в терминах протокола доступа и расположения в сети. Универсальный идентификатор ресурса (Uniform Resource Identifier, URI ) представляет собой уникальное имя некоторого ресурса. Смотрите на URI просто как на уникальную строку символов, идентифицирующую пространство имен.

По правилам SGML и XML, двоеточие может применяться в именах как обычный символ, поэтому имя с префиксом - это просто фокус, всякая программа, "не знающая" пространства имен, анализируя документ, рассматривает уточненное имя как обычное имя. Отсюда следует, в частности, что в объявлении типа документа (Document Type Declaration ) нельзя опускать префиксы имен.

Атрибут xmlns может появиться в любом элементе XML, а не только в корневом. Определенный им префикс можно применять в том элементе, в котором записан атрибут xmlns , и во всех вложенных в него элементах. Более того, в одном элементе можно определить несколько пространств имен.

Во вложенных элементах пространство имен можно переопределить, связав префикс с другим идентификатором.

Появление имени тега без префикса в документе, использующем пространство имен, означает, что имя принадлежит пространству имен по умолчанию (default namespace ).

Хорошо оформленный документ должен использовать пространства имен для всех своих элементов.

Префиксы, начинающиеся с символов xml с любым регистром букв, зарезервированы за самим языком XML. Префикс xmlns используется для связи другого, определяемого, префикса с идентификатором его пространства имен. Префикс xmlns не нужно определять, он введен рекомендацией "Namespaces in XML" и связан там с идентификатором пространства имен http://www.w3.ori/2000 /xmlns/ .

Еще один префикс, xml, связан в той же рекомендации с идентификатором http://www.w3.org/XML/1998/namespace . Его тоже не надо определять в документе XML. Никакой другой префикс не может быть связан с этими идентификаторами.preserve предписывает сохранять пробельные символы в неприкосновенности. Это важно для некоторых текстов, например, программных кодов. Значение default оставляет пробельные символы на усмотрение программы-обработчика.

Область действия

У деклараций пространств имен имеется область действия, так же, как у деклараций переменных в языках программирования. Это важно, так как пространства имен не всегда декларируются в начале документа XML, иногда это делается в последующих его разделах. Декларация пространства имен применима к элементу, в котором она появляется, а также к потомкам этого элемента, даже если она не определена там явным образом. Имя может ссылаться на пространство имен, только если используется в области действия его декларации.

Однако нам потребуется также смешивать области действия пространств имен в элементах, которые в противном случае наследовали бы другие пространства имен. В связи с этим определены два способа декларации области действия- default (по умолчанию) и qualified (квалифицированный).

Область действия по умолчанию

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

Чтобы пространство имен сделать пространством имен по умолчанию для некоторой области, достаточно опустить декларацию префикса.

Если префикс объявлен, а затем использован совместно с именем, то говорят что пространство имен явным образом установлено. Чтобы отнести к пространству имен неквалифицированное имя, необходимо объявить пространство по умолчанию, которое включает это неквалифицированное имя (без префикса).

Квалифицированная область действия

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

Классы и пространства имен

Классы.NET Framework

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

Базовые классы.NET представляют огромную коллекцию классов управляемого кода, позволяющие решать практически любые задачи, которые раньше можно было решать с помощью Windows API. Все эти классы следуют той же объектной модели IL с одиночным наследованием. Это значит, что можно либо создавать объекты любого из базовых классов.NET, либо наследовать от них собственные классы.

Отличие базовых классов.NET заключается в том, что они спроектированы интуитивно понятными и простыми в использовании. Например, для запуска потока необходимо вызвать метод Start() класса Thread . Чтобы сделать недоступным объект TextBox, свойству Enabled этого объекта присваивается значение false. Такой подход, хорошо знакомый разработчикам Visual Basic и Java, чьи библиотеки использовать столь же легко, принесет огромное облегчение разработчикам С++, которым в течение многих лет приходилось "воевать" с такими API-функциями, как GetDIBits(), RegisterWndClassEx() и IsEqualIID(), а также с множеством функций, которые требовали передачи дескрипторов окон.

Однако разработчики на С++ всегда имели легкий доступ к полному набору Windows API, в то время как разработчики на Visual Basic 6 и Java были ограничены в использовании базовой функциональности операционной системы, доступ к которой они получали из своих языков. Что касается базовых классов.NET, то они комбинируют простоту использования, присущую библиотекам Visual Basic и Java, с относительно полным покрытием набора функций Windows API. Многие средства Windows не доступны через базовые классы, и в этих случаях придется обращаться к API-функциям, но, в общем, это касается лишь наиболее экзотических функций. Для каждодневного применения набора базовых классов, в основном, будет достаточно. Но если понадобится вызвать API-функцию, то для этого.NET предоставляет так называемый механизм вызова платформы (platform-invoke) , гарантирующий корректное преобразование типов данных, поэтому теперь эта задача не труднее, чем вызов этих функций непосредственно из кода С++, причем независимо от того, на каком языке пишется код - C#, С++ или Visual Basic 2010.

Пространства имен

Пространства имен (namespace) - это способ, благодаря которому.NET избегает конфликтов имен между классами. Они предназначены для того, чтобы исключить ситуации, когда вы определяете класс, представляющий заказчика, называете его Customer, а после этого кто-то другой делает то же самое (подобный сценарий достаточно распространен).

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

Платформа.NET требует, чтобы все имена были объявлены в пределах пространства имен; например, вы можете поместить свой класс MyClass в пространство имен MyCompany . Тогда полное имя этого класса будет выглядеть как MyCompany.MyClass .

Запомните, что если пространство имен не указано явно, тип будет добавлен к безымянному глобальному пространству имен.

В большинстве ситуаций Microsoft рекомендует применять хотя бы два вложенных пространства имен: первое - наименование вашей компании, а второе - название технологии или пакета программного обеспечения, к которому относится класс, чтобы это выглядело примерно так: MyCompany.SomeNamespace.MyClass. В большинстве случаев такой подход защитит классы вашего приложения от возможных конфликтов с именами классов, написанных разработчиками из других компаний.

В следующей таблице приведен краткий список некоторых (но, конечно же, не всех) предлагаемых в.NET пространств имен, которые были поделены на группы на основе функциональности:

Ключевые пространства имен.NET Framework
Пространство имен в.NET Описание
System Внутри пространства имен System содержится множество полезных типов, позволяющих иметь дело с внутренними данными, математическими вычислениями, генерированием случайных чисел, переменными среды и сборкой мусора, а также ряд наиболее часто применяемых исключений и атрибутов
System.Collections
System.Collections.Generic
В этих пространствах имен содержится ряд контейнерных типов, а также несколько базовых типов и интерфейсов, которые позволяют создавать специальные коллекции
System.Data
System.Data.Common
System.Data.EntityClient
System.Data.SqlClient
Эти пространства имен применяются для взаимодействия с базами данных с помощью ADO.NET
System.IO
System.IO.Compression
System.IO.Ports
В этих пространствах содержится много типов, предназначенных для работы с операциями файлового ввода-вывода, сжатия данных и манипулирования портами
System.Reflection
System.Reflection.Emit
В этих пространствах имен содержатся типы, которые поддерживают обнаружение типов во время выполнения, а также динамическое создание типов
System.Runtime.InteropServices В этом пространстве имен содержатся средства, с помощью которых можно позволить типам.NET взаимодействовать с "неуправляемым кодом" (например, DLL-библиотеками на базе С и серверами СОМ) и наоборот
System.Drawing
System.Windows.Forms
В этих пространствах имен содержатся типы, применяемые для построения настольных приложений с использованием исходного набора графических инструментов.NET (Windows Forms)
System.Windows
System.Windows.Controls
System.Windows.Shapes
Пространство System.Windows является корневым среди этих нескольких пространств имен, которые представляют собой набор графических инструментов Windows Presentation Foundation (WPF)
System.Linq
System.Xml.Linq
System.Data.DataSetExtensions
В этих пространствах имен содержатся типы, применяемые при выполнении программирования с использованием API-интерфейса LINQ
System.Web Это пространство имен является одним из многих, которые позволяют создавать веб-приложения ASP.NET
System.ServiceModel Это пространство имен является одним из многих, которые позволяется применять для создания распределенных приложений с помощью API-интерфейса Windows Communication Foundation (WCF)
System.Workflow.Runtime
System.Workflow.Activities
Эти два пространства имен являются главными представителями многочисленных пространств имен, в которых содержатся типы, применяемые для построения поддерживающих рабочие потоки приложений с помощью API-интерфейса Windows Workflow Foundation (WWF)
System.Threading
System.Threading.Tasks
В этом пространстве имен содержатся многочисленные типы для построения многопоточных приложений, способных распределять рабочую нагрузку среди нескольких ЦП.
System.Security Безопасность является неотъемлемым свойством мира.NET. В относящихся к безопасности пространствах имен содержится множество типов, которые позволяют иметь дело с разрешениями, криптографической защитой и т.д
System.Xml В этом ориентированном на XML пространстве имен содержатся многочисленные типы, которые можно применять для взаимодействия с XML-данными

Роль корневого пространства Microsoft

При изучении перечня, приведенного в таблице, нетрудно было заметить, что пространство имен System является корневым для приличного количества вложенных пространств имен (таких как System.IO, System.Data и т.д.). Как оказывается, однако, помимо System в библиотеке базовых классов предлагается еще и ряд других корневых пространств имен наивысшего уровня, наиболее полезным из которых является пространство имен Microsoft .

Предположим, что мы хотим предоставить в общее пользование наш класс Array, разработанный в предыдущих примерах. Однако не мы одни занимались этой проблемой; возможно, кем-то где-то, скажем, в одном из подразделений компании Intel был создан одноименный класс. Из-за того что имена этих классов совпадают, потенциальные пользователи не могут задействовать оба класса одновременно, они должны выбрать один из них. Эта проблема решается добавлением к имени класса некоторой строки, идентифицирующей его разработчиков, скажем,

Class Cplusplus_Primer_Third_Edition_Array { ... };

Конечно, это тоже не гарантирует уникальность имени, но с большой вероятностью избавит пользователя от данной проблемы. Как, однако, неудобно пользоваться столь длинными именами!
Стандарт С++ предлагает для решения проблемы совпадения имен механизм, называемый пространством имен . Каждый производитель программного обеспечения может заключить свои классы, функции и другие объекты в свое собственное пространство имен. Вот как выглядит, например, объявление нашего класса Array:

Namespace Cplusplus_Primer_3E { template class Array { ... }; }

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

Namespace IBM_Canada_Laboratory { template class Array { ... };
class Matrix { ... };
}
namespace Disney_Feature_Animation {
class Point { ... };
template class Array { ... };
}

По умолчанию в программе видны объекты, объявленные без явного указания пространства имен; они относятся к глобальному пространству имен. Для того чтобы обратиться к объекту из другого пространства, нужно использовать его квалифицированное имя, которое состоит из идентификатора пространства имен и идентификатора объекта, разделенных оператором разрешения области видимости (::). Вот как выглядят обращения к объектам приведенных выше примеров:

Cplusplus_Primer_3E::Array text; IBM_Canada_Laboratory::Matrix mat; Disney_Feature_Animation::Point origin(5000,5000);

Для удобства использования можно назначать псевдонимы пространствам имен. Псевдоним выбирают коротким и легким для запоминания. Например:

// псевдонимы namespace LIB = IBM_Canada_Laboratory; namespace DFA = Disney_Feature_Animation;
int main()
{
LIB::Array ia(1024);
}

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

Namespace LIB = Cplusplus_Primer_3E; int main() { LIB::Array ia(1024); }

Конечно, чтобы это стало возможным, необходимо точное совпадение интерфейсов классов и функций, объявленных в этих пространствах имен. Представим, что класс Array из Disney_Feature_Animation не имеет конструктора с одним параметром – размером. Тогда следующий код вызовет ошибку:

Namespace LIB = Disney_Feature_Animation;
int main()
{
LIB::Array ia(1024);
}

Еще более удобным является способ использования простого, неквалифицированного имени для обращения к объектам, определенным в некотором пространстве имен. Для этого существует директива using:
#include "IBM_Canada_Laboratory.h"

Using namespace IBM_Canada_Laboratory;
int main()
{
Matrix mat(4,4);
// IBM_Canada_Laboratory::Array
Array ia(1024);
// ...
}

Пространство имен IBM_Canada_Laboratory становится видимым в программе. Можно сделать видимым не все пространство, а отдельные имена внутри него (селективная директива using):

#include "IBM_Canada_Laboratory.h" using namespace IBM_Canada_Laboratory::Matrix;
// видимым становится только Matrix
int main()
{
// IBM_Canada_Laboratory::Matrix
Matrix mat(4,4); // Ошибка: IBM_Canada_Laboratory::Array невидим
Array ia(1024);
// ... }

Как мы уже упоминали, все компоненты стандартной библиотеки С++ объявлены внутри пространства имен std. Поэтому простого включения заголовочного файла недостаточно, чтобы напрямую пользоваться стандартными функциями и классами:

#include // ошибка: string невидим

Необходимо использовать директиву using:

#include using namespace std; // Ok: видим string
string current_chapter = "Обзор С++";

Заметим, однако, что таким образом мы возвращаемся к проблеме “засорения” глобального пространства имен, ради решения которой и был создан механизм именованных пространств. Поэтому лучше использовать либо квалифицированное имя:

#include // правильно: квалифицированное имя std::string current_chapter = "Обзор С++"; либо селективную директиву using: #include using namespace std::string; // Ok: string видим
string current_chapter = "Обзор С++";

Мы рекомендуем пользоваться последним способом.
В большинстве примеров этой книги директивы пространств имен были опущены. Это сделано ради сокращения размера кода, а также потому, что большинство примеров были скомпилированы компилятором, не поддерживающим пространства имен – достаточно недавнего нововведения С++. (Детали применения using-объявлений при работе с стандартной библиотекой С++ обсуждаются в разделе 8.6.)
В нижеследующих главах мы создадим еще четыре класса: String, Stack, List и модификацию Stack. Все они будут заключены в одно пространство имен – Cplusplus_Primer_3E. (Более подробно работа с пространствами имен рассматривается в главе 8.)

Упражнение 2.21

Дано пространство имен

Namespace Exercize { template class Array { ... };
template
void print (Array< EType >);
class String { ... }
template
class List { ... };
}

и текст программы:

Int main() { const int size = 1024; Array as (size); List il (size);
// ...
Array *pas = new Array(as);
List *pil = new List(il);
print (*pas);
}

Программа не компилируется, поскольку объявления используемых классов заключены в пространство имен Exercise. Модифицируйте код программы, используя
(a) квалифицированные имена
(b) селективную директиву using
(c) механизм псевдонимов
(d) директиву using

Что такое пространство имен в C++?

Пространство имен (namespace) - это способ объединения логически связанных объявлений под общим именем.

Пример пространства имен:

// @author Subbotin B.P..h" namespace first { int a; float b; } namespace second { int a; float b; } int _tmain(int argc, _TCHAR* argv) { first::a = 1; second::a = 2; first::b = 1.23; second::b = 4.56; printf("\nfirst::a = %d\n", first::a); printf("\nsecond::a = %d\n", second::a); printf("\nfirst::b = %.2f\n", first::b); printf("\nsecond::b = %.2f\n\n", second::b); return 0; }

Получаем:

В примере созданы два пространства имен: first и second. Оба пространства содержат одинаковые переменные. Но именно факт принадлежности, например, переменной a к пространству first не позволяет её спутать с переменной из другого пространства имён. Это позволяет избегать конфликта имен.

означает, что используется переменная int а, объявленная в пространстве имен first. Это пример using-объявления. Оператор:: называется оператором определения области видимости.

Создаются пространства имен при помощи ключевого слова namespace:

Namespace first { int a; float b; }

Для того, чтобы использовать все имена из пространства имен можно применить директиву using namespace. Пример использования using namespace std:

using namespace std; int _tmain(int argc, _TCHAR* argv) { cout<<"\n using namespace std \n"<

using namespace std позволяет использовать имена из пространства имен std. std - это имя стандартной библиотеки C++.

Если в последнем примере убрать строку подключения пространства имен using namespace std, то надо будет указывать наименование пространства имен явно:

// @author Subbotin B.P..h" #include int _tmain(int argc, _TCHAR* argv) { std::cout<<"\n using namespace std \n"<

Пространство имен определяет область видимости. В примерах явно определялись пространства имён. А вот другие примеры пространств имен. Область видимости внутри функции - это тоже пространство имен. Область видимости глобальных переменных - это тоже пространство имен. Класс - это тоже пространство имен.

Возможно создание пространства имен без имени. Пример:

// @author Subbotin B.P..h" namespace { int a; int b; } int _tmain(int argc, _TCHAR* argv) { a = 5; b = 8; printf("\n a = %d\n", a); printf("\n b = %d\n\n", b); return 0; }

Здесь подразумевается использование директивы using namespace. Такие пространства имен нужны для ухода от возможного конфликта имен.

Если название пространства имен слишком длинное, то можно создать псевдоним пространства имен. Пример:

// @author Subbotin B.P..h" namespace underground { int a; int b; } namespace ug = underground; int _tmain(int argc, _TCHAR* argv) { ug::a = 5; ug::b = 8; printf("\n ug::a = %d\n", ug::a); printf("\n ug::b = %d\n\n", ug::b); return 0; }

namespace ug = underground;

вводит псевдоним ug для пространства имен underground. Далее мы работаем с псевдонимом.

Если предполагается использовать только часть имён из пространства имен, то можно отобрать эту часть в новое пространство имен и использовать его. Пример:

// @author Subbotin B.P..h" namespace underground { int a; int b; int c; float d; double e; } namespace ug { using underground::a; using underground::b; } int _tmain(int argc, _TCHAR* argv) { ug::a = 5; ug::b = 8; printf("\n ug::a = %d\n", ug::a); printf("\n ug::b = %d\n\n", ug::b); return 0; }

Здесь из пяти переменных пространства имен underground мы предполагаем использовать только две. Создаём новое пространство имен ug, в котором имеются два using-объявления. Далее мы работаем с пространством имен ug.

Пространство имен можно изменить, т.е. дописать в него новые объявления. Пример:

// @author Subbotin B.P..h" namespace underground { int a; int b; } namespace underground { float c; } int _tmain(int argc, _TCHAR* argv) { underground::a = 5; underground::b = 8; underground::c = 1.2; printf("\n underground::a = %d\n", underground::a); printf("\n underground::b = %d\n", underground::b); printf("\n underground::c = %.1f\n\n", underground::c); return 0; }

Получаем:

Пространства имен можно вкладывать друг в друга Пример:

// @author Subbotin B.P..h" namespace upper { int a; int b; namespace inner { float c; } } int _tmain(int argc, _TCHAR* argv) { upper::a = 5; upper::b = 8; upper::inner::c = 1.2; printf("\n upper::a = %d\n", upper::a); printf("\n upper::b = %d\n", upper::b); printf("\n upper::inner::c = %.1f\n\n", upper::inner::c); return 0; }

Получаем:

В примере namespace upper содержит namespace inner. Обратите внимание, как идёт обращение к полю внутреннего пространства имен:

upper::inner::c = 1.2;

Рассмотрим глобальное пространство имен. Здесь используют оператор:: без указания имени пространства. В глобальное пространство имен попадают глобальные объявления, включая соответствующие using-директивы. Пример глобального пространства имен:

// @author Subbotin B.P..h" #include using namespace std; int nVar; int _tmain(int argc, _TCHAR* argv) { int nAnotherVar = 1; ::nVar = 5; cout<<"\n nAnotherVar = "<

Важно увидеть разницу между using-объявлениями и using-директивами.
using-объявление делает доступной переменную в локальной области видимости, т.е. происходит локальное объявление имени. Объявить локальную переменную можно двумя путями: обычным или посредством using-объявления.

using-директива делает доступными все имена из данного пространства имен, но не объявляет их локально.

using-объявление имеет приоритет перед using-директивой.

Рассмотрим пример:

// @author Subbotin B.P..h" namespace sbp { int a; int b; int c; } int a; int _tmain(int argc, _TCHAR* argv) { int a; using namespace sbp; a = 1; sbp::a = 2; ::a = 3; printf("\n a = %d\n", a); printf("\n sbp::a = %d\n", sbp::a); printf("\n::a = %d\n\n", ::a); return 0; }

Получаем:

using namespace sbp;

это using-директива, которая делает доступными все имена из пространства имен sbp.

это работа с локальной переменной а. Чтоб присвоить значения переменной а из пространства sbp, надо явно указать на sbp:

Это же относится и к глобальной переменной а.

Локальная переменная а закрывает глобальные переменные с тем же именем.

Теперь пример для using-объявления:

// @author Subbotin B.P..h" namespace sbp { int a; int b; int c; } int a; int _tmain(int argc, _TCHAR* argv) { int a; a = 1; using sbp::b; b = 2; ::a = 3; printf("\n a = %d\n", a); printf("\n sbp::b = %d\n", sbp::b); printf("\n::a = %d\n\n", ::a); return 0; }

Получаем:

это using-объявление. Здесь локально объявляется переменная b из пространства имён sbp. После этого объявления можно проводить действия:

но using-объявление для а

привело бы нас к ошибке, ведь в примере уже определена локальная переменная а.

 

 

Это интересно: