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

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

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

Например, Андрей работает в компании X, а ID (сокр. от англ. Identifier — идентификатор) его как работника равен 123. Олег работает в компании Y, а его ID также равен 123. Единственное (с точки зрения некоей системы учета) , благодаря чему Андрей и Олег могут быть различимы при совпадающих ID, это их принадлежность к разным компаниям. Различие компаний в этом случае представляет собой систему различных пространств имён (одна компания — одно пространство) . Наличие двух работников в компании с одинаковыми ID представляет большие проблемы при их использовании, например, по платёжному чеку, в котором будет указан работник с ID 123, будет весьма затруднительно определить работника, которому этот чек предназначается.

дополню применимо ближе к программированию

пример: Вы подключили две библиотеки разных разработчиков к своему проекту; в одной библиотеке есть класс list и во второй библиотеке есть класс list — как быть? , чтобы не было путаницы — используется пространство имен

Здравствуйте, дорогие читатели!

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

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

Для начала, давайте попробуем понять для чего вообще нужны эти самые пространства имен.

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

Пространство имен — это декларативная область, в рамках которой определяются различные идентификаторы (имена типов, функций, переменных, и т. д.). A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Пространства имен используются для организации кода в виде логических групп и с целью избежания конфликтов имен, которые могут возникнуть, особенно в таких случаях, когда база кода включает несколько библиотек. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries. Все идентификаторы в пределах пространства имен доступны друг другу без уточнения. All identifiers at namespace scope are visible to one another without qualification. Идентификаторы за пределами пространства имен могут обращаться к членам с помощью полного имени каждого идентификатора, например std::vector vec; или else с помощью объявления using для одного идентификатора ( using std::string ) или директивы using для всех идентификаторов в пространстве имен ( using namespace std; ). Identifiers outside the namespace can access the members by using the fully qualified name for each identifier, for example std::vector vec; , or else by a using Declaration for a single identifier ( using std::string ), or a using Directive for all the identifiers in the namespace ( using namespace std; ). Код в файлах заголовков всегда должен содержать полное имя в пространстве имен. Code in header files should always use the fully qualified namespace name.

В следующем примере показано объявление пространства имен и продемонстрированы три способа доступа к членам пространства имен из кода за его пределами. The following example shows a namespace declaration and three ways that code outside the namespace can accesses their members.

Читайте также:  Как сделать рисунок прозрачным в word

Использование полного имени: Use the fully qualified name:

Чтобы добавить в область видимости один идентификатор, используйте объявление using: Use a using declaration to bring one identifier into scope:

Чтобы добавить в область видимости все идентификаторы пространства имен, используйте директиву using: Use a using directive to bring everything in the namespace into scope:

директивы using using directives

Директива using позволяет использовать все имена в пространстве имен без имени пространства имен в качестве явного квалификатора. The using directive allows all the names in a namespace to be used without the namespace-name as an explicit qualifier. Использование директивы using в файле реализации (т. е. *. cpp) при использовании нескольких различных идентификаторов в пространстве имен; Если вы используете только один или два идентификатора, рассмотрите использование объявления using, чтобы привести эти идентификаторы в область, а не все идентификаторы в пространстве имен. Use a using directive in an implementation file (i.e. *.cpp) if you are using several different identifiers in a namespace; if you are just using one or two identifiers, then consider a using declaration to only bring those identifiers into scope and not all the identifiers in the namespace. Если локальная переменная имеет такое же имя, как и переменная пространства имен, то переменная пространства имен будет скрытой. If a local variable has the same name as a namespace variable, the namespace variable is hidden. Создавать переменную пространства имен с те же именем, что и у глобальной переменной, является ошибкой. It is an error to have a namespace variable with the same name as a global variable.

Директиву using можно поместить в верхнюю часть CPP-файла (в области видимости файла) или внутрь определения класса или функции. A using directive can be placed at the top of a .cpp file (at file scope), or inside a class or function definition.

Без особой необходимости не размещайте директивы using в файлах заголовков (*.h), так как любой файл, содержащий этот заголовок, добавит все идентификаторы пространства имен в область видимости, что может вызвать скрытие или конфликты имен, которые очень трудно отлаживать. In general, avoid putting using directives in header files (*.h) because any file that includes that header will bring everything in the namespace into scope, which can cause name hiding and name collision problems that are very difficult to debug. В файлах заголовков всегда используйте полные имена. Always use fully qualified names in a header file. Если эти имена получаются слишком длинными, используйте псевдоним пространства имен для их сокращения. If those names get too long, you can use a namespace alias to shorten them. (См. ниже.) (See below.)

Объявление пространств имен и их членов Declaring namespaces and namespace members

Как правило, пространство имен объявляется в файле заголовка. Typically, you declare a namespace in a header file. Если реализации функций находятся в отдельном файле, определяйте имена функций полностью, как показано в следующем примере. If your function implementations are in a separate file, then qualify the function names, as in this example.

Реализации функций в контосодата. cpp должны использовать полное имя, даже если поместить директиву using в начало файла: Function implementations in contosodata.cpp should use the fully qualified name, even if you place a using directive at the top of the file:

Пространство имен может быть объявлено в нескольких блоках в одном файле и в нескольких файлах. A namespace can be declared in multiple blocks in a single file, and in multiple files. Компилятор соединит вместе все части во время предварительной обработки и полученное в результате пространство имен будет содержать все члены, объявленные во всех частях. The compiler joins the parts together during preprocessing and the resulting namespace contains all the members declared in all the parts. Примером этого является пространство имен std, которое объявляется в каждом из файлов заголовка в стандартной библиотеке. An example of this is the std namespace which is declared in each of the header files in the standard library.

Читайте также:  Метал гир солид ревендженс

Члены именованного пространства имен могут определяться за его границами, если они объявлены путем явной квалификации определяемого пространства имен. Members of a named namespace can be defined outside the namespace in which they are declared by explicit qualification of the name being defined. Однако определение должно располагаться после точки объявления в пространстве имен, окружающем то пространство имен, где находится объявление. However, the definition must appear after the point of declaration in a namespace that encloses the declaration’s namespace. Пример: For example:

Эта ошибка может возникнуть, когда члены пространства имен объявляются в нескольких файлах заголовка и эти заголовки не включены в правильном порядке. This error can occur when namespace members are declared across multiple header files, and you have not included those headers in the correct order.

Глобальное пространство имен The global namespace

Если идентификатор не объявлен явно в пространстве имен, он неявно считается входящим в глобальное пространство имен. If an identifier is not declared in an explicit namespace, it is part of the implicit global namespace. В общем случае старайтесь не делать объявления в глобальной области, если это возможно, за исключением функции Mainточки входа, которая должна находиться в глобальном пространстве имен. In general, try to avoid making declarations at global scope when possible, except for the entry point main Function, which is required to be in the global namespace. Чтобы явно указать глобальный идентификатор, используйте оператор разрешения области видимости без имени, как сделано в ::SomeFunction(x); . To explicitly qualify a global identifier, use the scope resolution operator with no name, as in ::SomeFunction(x); . Это позволит отличать данный идентификатор от любого другого элемента с таким же именем, находящегося в другом пространстве имен. Кроме того, это облегчит понимание кода. This will differentiate the identifier from anything with the same name in any other namespace, and it will also help to make your code easier for others to understand.

Пространство имен std The std namespace

Все C++ типы и функции стандартных библиотек объявляются в std пространстве имен или пространствах имен, вложенных в std . All C++ standard library types and functions are declared in the std namespace or namespaces nested inside std .

Вложенные пространства имен Nested namespaces

Пространства имен могут быть вложенными. Namespaces may be nested. Обычное вложенное пространство имен имеет неограниченный доступ к членам своего родительского пространства, но члены родительского пространства не имеют неограниченного доступа к вложенному пространству имен (если оно не объявлено как встроенное), что показано в следующем примере. An ordinary nested namespace has unqualified access to its parent’s members, but the parent members do not have unqualified access to the nested namespace (unless it is declared as inline), as shown in the following example:

Обычные вложенные пространства имен можно использовать для инкапсуляции данных о внутренней реализации, которые не являются частью открытого интерфейса родительского пространства имен. Ordinary nested namespaces can be used to encapsulate internal implementation details that are not part of the public interface of the parent namespace.

Встроенные пространства имен (C++ 11) Inline namespaces (C++ 11)

В отличие от обычных вложенных пространств имен члены встроенного пространства имен обрабатываются как члены родительского пространства имен. In contrast to an ordinary nested namespace, members of an inline namespace are treated as members of the parent namespace. Эта особенность позволяет выполнять поиск перегруженных функций с зависимостью от аргументов среди функции, которые имеют перегрузки в родительском и вложенном встроенном пространстве имен. This characteristic enables argument dependent lookup on overloaded functions to work on functions that have overloads in a parent and a nested inline namespace. Это также позволяет объявлять специализации в родительском пространстве имен для шаблонов, объявленных во встроенном пространстве имен. It also enables you to declare a specialization in a parent namespace for a template that is declared in the inline namespace. В следующем примере показано, как внешний код привязывается к встроенному пространству имен по умолчанию. The following example shows how external code binds to the inline namespace by default:

Читайте также:  Программа для движения курсора мыши

В следующем примере показано, как можно объявить специализацию в родительском пространстве имен шаблона, объявленного во встроенном пространстве имен. The following example shows how you can declare a specialization in a parent of a template that is declared in an inline namespace:

Встроенные пространства имен можно использовать как механизм управления версиями для управления изменениями в открытом интерфейсе библиотеки. You can use inline namespaces as a versioning mechanism to manage changes to the public interface of a library. Например, можно создать одно родительское пространство имен и инкапсулировать каждую версию интерфейса в своем собственном пространстве имен, вложенном в родительское. For example, you can create a single parent namespace, and encapsulate each version of the interface in its own namespace nested inside the parent. Пространство имен, которое содержит самую последнюю или основную версию, квалифицируется как встроенное и поэтому представляется так, будто оно является непосредственным членом родительского пространства имен. The namespace that holds the most recent or preferred version is qualified as inline, and is therefore exposed as if it were a direct member of the parent namespace. Клиентский код, вызывающий Parent::Class, автоматически привязывается к новому коду. Client code that invokes the Parent::Class will automatically bind to the new code. Клиенты, которые предпочитают использовать старую версию, могут по-прежнему получить доступ к ней, используя полный путь к вложенному пространству имен, содержащему данный код. Clients that prefer to use the older version can still access it by using the fully qualified path to the nested namespace that has that code.

Ключевое слово inline должно применяться к первому объявлению пространства имен в единице компиляции. The inline keyword must be applied to the first declaration of the namespace in a compilation unit.

В следующем примере показано две версии интерфейса: каждое — во вложенном пространстве имен. The following example shows two versions of an interface, each in a nested namespace. Пространство имен v_20 содержит некоторые изменения из интерфейса v_10 и помечается как встроенное. The v_20 namespace has some modification from the v_10 interface and is marked as inline. Клиентский код, который использует новую библиотеку и вызывает Contoso::Funcs::Add , вызовет версию v_20. Client code that uses the new library and calls Contoso::Funcs::Add will invoke the v_20 version. Код, который пытается вызвать Contoso::Funcs::Divide , теперь будет вызывать ошибку времени компиляции. Code that attempts to call Contoso::Funcs::Divide will now get a compile time error. Если действительно требуется эта функция, доступ к версии v_10 можно получить путем явного вызова Contoso::v_10::Funcs::Divide . If they really need that function, they can still access the v_10 version by explicitly calling Contoso::v_10::Funcs::Divide .

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

Имена пространств имен должны быть уникальными, из-за чего зачастую они получаются не слишком короткими. Namespace names need to be unique, which means that often they should not be too short. Если длинное имя оказывается трудночитаемым или его сложно вводить в файле заголовка, где нельзя использовать директиву using, можно создать псевдоним пространства имен, который будет служить в качестве сокращения фактического имени. If the length of a name makes code difficult to read, or is tedious to type in a header file where using directives can’t be used, then you can make a namespace alias which serves as an abbreviation for the actual name. Пример: For example:

анонимные или безымянные пространства имен anonymous or unnamed namespaces

Вы можете создать явное пространство имен, но не присвоить ему имя. You can create an explicit namespace but not give it a name:

Ссылка на основную публикацию
Что делать если завис телефон андроид
Что делать, если завис Андроид и не реагирует не на что? В этой статье мы посмотрим четыре простых способа как...
Фум лента в стоматологии фото
Автор: G. Freedman Перевод: Александр Зыбайло Автор: G. Freedman Перевод: Александр Зыбайло Ограничение количества цемента для фиксации и использование определенной...
Функции жесткого диска в компьютере
Жесткий диск, он же винчестер, является основным местом, где хранится вся информация. В отличие от оперативной памяти, он энергетически независим,...
Что дают за рейтинговые бои
В кои-то веки разработчики решили прислушаться к мнению игроков и ввести в Варфейс рейтинговые матчи. Теперь каждый игрок, достигший 26...
Adblock detector