Что такое using namespace

Namespaces (C++)

The following example shows a namespace declaration and three ways that code outside the namespace can accesses their members.

Use the fully qualified name:

Use a using declaration to bring one identifier into scope:

Use a using directive to bring everything in the namespace into scope:

using directives

The using directive allows all the names in a namespace to be used without the namespace-name as an explicit qualifier. 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.

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.

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. 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

The std namespace

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.

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. 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.

The inline keyword must be applied to the first declaration of the namespace in a compilation unit.

Namespace aliases

Namespace names need to be unique, which means that often they should not be too short. 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:

Источник

Изучаем C++. Часть 8. Библиотеки и пространства имён

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

Что такое using namespace. Смотреть фото Что такое using namespace. Смотреть картинку Что такое using namespace. Картинка про Что такое using namespace. Фото Что такое using namespace

Что такое using namespace. Смотреть фото Что такое using namespace. Смотреть картинку Что такое using namespace. Картинка про Что такое using namespace. Фото Что такое using namespace

Это восьмая часть из серии статей «Глубокое погружение в C++». В прошлой статье мы узнали, как хранить данные в массивах. Сегодня — ещё интереснее.

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

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

Что такое using namespace. Смотреть фото Что такое using namespace. Смотреть картинку Что такое using namespace. Картинка про Что такое using namespace. Фото Что такое using namespace

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

Пространства имён в C++

Пространство имён (англ. namespace) — это группа взаимосвязанных функций, переменных, констант, классов, объектов и других компонентов программы.

С самого начала изучения C++ мы используем команду std: cout, чтобы выводить данные в терминал. На самом деле команда называется просто cout, а std — это пространство имён, в котором она находится.

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

Вот пример создания пространства имён:

Мы объединяем в группу несколько разных команд и избегаем конфликтов имён. Это нужно, когда в какой-то из подключённых вами библиотек уже есть функция, например sum (). По пространству имён программа поймёт, какая именно функция вам нужна.

Если же вы хотите сократить код, то используйте команду using:

В данном случае команда говорит, что вам нужны имена из mynames и std, поэтому никакой ошибки выведено не будет.

Также после using можно указать не целое пространство имён, а только отдельную функцию или переменную:

Файлы заголовков в C++

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

Здесь нет функции main (), потому что этот код — не самостоятельная программа, а библиотека для других программ. Следовательно, точка входа здесь не нужна. Также мы не подключаем iostream, потому что не собираемся ничего выводить, но вы можете добавить в свой заголовок любые другие файлы.

Поместите mylib.h в папку, где находится ваша программа. Затем добавьте в начало кода команду:

Обратите внимание на двойные кавычки вместо угловых скобок: первые используются для локальных заголовков, а вторые — для системных.

Теперь вы можете использовать весь функционал из этой библиотеки:

Вот что будет выведено:

Что такое using namespace. Смотреть фото Что такое using namespace. Смотреть картинку Что такое using namespace. Картинка про Что такое using namespace. Фото Что такое using namespace

Обратите внимание, что функция pow, как и другие математические функции, существует также и в библиотеке cmath.

Заключение

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

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

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

Источник

Namespaces

C# programs are organized using namespaces. Namespaces are used both as an «internal» organization system for a program, and as an «external» organization system—a way of presenting program elements that are exposed to other programs.

Using directives (Using directives) are provided to facilitate the use of namespaces.

Compilation units

A compilation_unit defines the overall structure of a source file. A compilation unit consists of zero or more using_directives followed by zero or more global_attributes followed by zero or more namespace_member_declarations.

A C# program consists of one or more compilation units, each contained in a separate source file. When a C# program is compiled, all of the compilation units are processed together. Thus, compilation units can depend on each other, possibly in a circular fashion.

The using_directives of a compilation unit affect the global_attributes and namespace_member_declarations of that compilation unit, but have no effect on other compilation units.

The global_attributes (Attributes) of a compilation unit permit the specification of attributes for the target assembly and module. Assemblies and modules act as physical containers for types. An assembly may consist of several physically separate modules.

The namespace_member_declarations of each compilation unit of a program contribute members to a single declaration space called the global namespace. For example:

Namespace declarations

A namespace_declaration may occur as a top-level declaration in a compilation_unit or as a member declaration within another namespace_declaration. When a namespace_declaration occurs as a top-level declaration in a compilation_unit, the namespace becomes a member of the global namespace. When a namespace_declaration occurs within another namespace_declaration, the inner namespace becomes a member of the outer namespace. In either case, the name of a namespace must be unique within the containing namespace.

Namespaces are implicitly public and the declaration of a namespace cannot include any access modifiers.

Within a namespace_body, the optional using_directives import the names of other namespaces, types and members, allowing them to be referenced directly instead of through qualified names. The optional namespace_member_declarations contribute members to the declaration space of the namespace. Note that all using_directives must appear before any member declarations.

is semantically equivalent to

Namespaces are open-ended, and two namespace declarations with the same fully qualified name contribute to the same declaration space (Declarations). In the example

Extern aliases

An extern_alias_directive introduces an identifier that serves as an alias for a namespace. The specification of the aliased namespace is external to the source code of the program and applies also to nested namespaces of the aliased namespace.

The scope of an extern_alias_directive extends over the using_directives, global_attributes and namespace_member_declarations of its immediately containing compilation unit or namespace body.

An extern_alias_directive makes an alias available within a particular compilation unit or namespace body, but it does not contribute any new members to the underlying declaration space. In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.

Using directives

Using directives facilitate the use of namespaces and types defined in other namespaces. Using directives impact the name resolution process of namespace_or_type_names (Namespace and type names) and simple_names (Simple names), but unlike declarations, using directives do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used.

A using_alias_directive (Using alias directives) introduces an alias for a namespace or type.

A using_namespace_directive (Using namespace directives) imports the type members of a namespace.

A using_static_directive (Using static directives) imports the nested types and static members of a type.

The scope of a using_directive extends over the namespace_member_declarations of its immediately containing compilation unit or namespace body. The scope of a using_directive specifically does not include its peer using_directives. Thus, peer using_directives do not affect each other, and the order in which they are written is insignificant.

Using alias directives

A using_alias_directive introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body.

Within member declarations in a compilation unit or namespace body that contains a using_alias_directive, the identifier introduced by the using_alias_directive can be used to reference the given namespace or type. For example:

The identifier of a using_alias_directive must be unique within the declaration space of the compilation unit or namespace that immediately contains the using_alias_directive. For example:

A using_alias_directive makes an alias available within a particular compilation unit or namespace body, but it does not contribute any new members to the underlying declaration space. In other words, a using_alias_directive is not transitive but rather affects only the compilation unit or namespace body in which it occurs. In the example

the scope of the using_alias_directive that introduces R only extends to member declarations in the namespace body in which it is contained, so R is unknown in the second namespace declaration. However, placing the using_alias_directive in the containing compilation unit causes the alias to become available within both namespace declarations:

Just like regular members, names introduced by using_alias_directives are hidden by similarly named members in nested scopes. In the example

The order in which using_alias_directives are written has no significance, and resolution of the namespace_or_type_name referenced by a using_alias_directive is not affected by the using_alias_directive itself or by other using_directives in the immediately containing compilation unit or namespace body. In other words, the namespace_or_type_name of a using_alias_directive is resolved as if the immediately containing compilation unit or namespace body had no using_directives. A using_alias_directive may however be affected by extern_alias_directives in the immediately containing compilation unit or namespace body. In the example

the last using_alias_directive results in a compile-time error because it is not affected by the first using_alias_directive. The first using_alias_directive does not result in an error since the scope of the extern alias E includes the using_alias_directive.

A using_alias_directive can create an alias for any namespace or type, including the namespace within which it appears and any namespace or type nested within that namespace.

Accessing a namespace or type through an alias yields exactly the same result as accessing that namespace or type through its declared name. For example, given

Using aliases can name a closed constructed type, but cannot name an unbound generic type declaration without supplying type arguments. For example:

Using namespace directives

A using_namespace_directive imports the types contained in a namespace into the immediately enclosing compilation unit or namespace body, enabling the identifier of each type to be used without qualification.

Within member declarations in a compilation unit or namespace body that contains a using_namespace_directive, the types contained in the given namespace can be referenced directly. For example:

A using_namespace_directive imports the types contained in the given namespace, but specifically does not import nested namespaces. In the example

Unlike a using_alias_directive, a using_namespace_directive may import types whose identifiers are already defined within the enclosing compilation unit or namespace body. In effect, names imported by a using_namespace_directive are hidden by similarly named members in the enclosing compilation unit or namespace body. For example:

When more than one namespace or type imported by using_namespace_directives or using_static_directives in the same compilation unit or namespace body contain types by the same name, references to that name as a type_name are considered ambiguous. In the example

Furthermore, when more than one namespace or type imported by using_namespace_directives or using_static_directives in the same compilation unit or namespace body contain types or members by the same name, references to that name as a simple_name are considered ambiguous. In the example

Like a using_alias_directive, a using_namespace_directive does not contribute any new members to the underlying declaration space of the compilation unit or namespace, but rather affects only the compilation unit or namespace body in which it appears.

The namespace_name referenced by a using_namespace_directive is resolved in the same way as the namespace_or_type_name referenced by a using_alias_directive. Thus, using_namespace_directives in the same compilation unit or namespace body do not affect each other and can be written in any order.

Using static directives

A using_static_directive imports the nested types and static members contained directly in a type declaration into the immediately enclosing compilation unit or namespace body, enabling the identifier of each member and type to be used without qualification.

Within member declarations in a compilation unit or namespace body that contains a using_static_directive, the accessible nested types and static members (except extension methods) contained directly in the declaration of the given type can be referenced directly. For example:

A using_static_directive specifically does not import extension methods directly as static methods, but makes them available for extension method invocation (Extension method invocations). In the example

A using_static_directive only imports members and types declared directly in the given type, not members and types declared in base classes.

Ambiguities between multiple using_namespace_directives and using_static_directives are discussed in Using namespace directives.

Namespace members

A namespace_member_declaration is either a namespace_declaration (Namespace declarations) or a type_declaration (Type declarations).

A compilation unit or a namespace body can contain namespace_member_declarations, and such declarations contribute new members to the underlying declaration space of the containing compilation unit or namespace body.

Type declarations

A type_declaration can occur as a top-level declaration in a compilation unit or as a member declaration within a namespace, class, or struct.

A type declared within a class or struct is called a nested type (Nested types).

The permitted access modifiers and the default access for a type declaration depend on the context in which the declaration takes place (Declared accessibility):

Namespace alias qualifiers

A qualified_alias_member is defined as follows:

A qualified_alias_member can be used as a namespace_or_type_name (Namespace and type names) or as the left operand in a member_access (Member access).

A qualified_alias_member has one of two forms:

Using this notation, the meaning of a qualified_alias_member is determined as follows:

Otherwise, starting with the namespace declaration (Namespace declarations) immediately containing the qualified_alias_member (if any), continuing with each enclosing namespace declaration (if any), and ending with the compilation unit containing the qualified_alias_member, the following steps are evaluated until an entity is located:

Otherwise, the qualified_alias_member is undefined and a compile-time error occurs.

Uniqueness of aliases

Each compilation unit and namespace body has a separate declaration space for extern aliases and using aliases. Thus, while the name of an extern alias or using alias must be unique within the set of extern aliases and using aliases declared in the immediately containing compilation unit or namespace body, an alias is permitted to have the same name as a type or namespace as long as it is used only with the :: qualifier.

Источник

Пространства имен (C++)

В следующем примере показано объявление пространства имен и продемонстрированы три способа доступа к членам пространства имен из кода за его пределами.

Использование полного имени:

Чтобы добавить в область видимости один идентификатор, используйте объявление using:

Чтобы добавить в область видимости все идентификаторы пространства имен, используйте директиву using:

Директивы using

using Директива позволяет использовать все имена в namespace для использования без using в качестве явного квалификатора. Использование директивы using в файле реализации (т. е. *. cpp) при использовании нескольких различных идентификаторов в пространстве имен; Если вы используете только один или два идентификатора, рассмотрите использование объявления using, чтобы привести эти идентификаторы в область, а не все идентификаторы в пространстве имен. Если локальная переменная имеет такое же имя, как и переменная пространства имен, то переменная пространства имен будет скрытой. Создавать переменную пространства имен с те же именем, что и у глобальной переменной, является ошибкой.

Директиву using можно поместить в верхнюю часть CPP-файла (в области видимости файла) или внутрь определения класса или функции.

Без особой необходимости не размещайте директивы using в файлах заголовков (*.h), так как любой файл, содержащий этот заголовок, добавит все идентификаторы пространства имен в область видимости, что может вызвать скрытие или конфликты имен, которые очень трудно отлаживать. В файлах заголовков всегда используйте полные имена. Если эти имена получаются слишком длинными, используйте псевдоним пространства имен для их сокращения. (См. ниже.)

Объявление пространств имен и их членов

Как правило, пространство имен объявляется в файле заголовка. Если реализации функций находятся в отдельном файле, определяйте имена функций полностью, как показано в следующем примере.

Реализации функций в контосодата. cpp должны использовать полное имя, даже если поместить using директиву в начало файла:

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

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

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

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

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

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

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

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

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

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

В следующем примере показано, как можно объявить специализацию в родительском пространстве имен шаблона, объявленного во встроенном пространстве имен.

Встроенные пространства имен можно использовать как механизм управления версиями для управления изменениями в открытом интерфейсе библиотеки. Например, можно создать одно родительское пространство имен и инкапсулировать каждую версию интерфейса в своем собственном пространстве имен, вложенном в родительское. Пространство имен, которое содержит самую последнюю или основную версию, квалифицируется как встроенное и поэтому представляется так, будто оно является непосредственным членом родительского пространства имен. Клиентский код, вызывающий Parent::Class, автоматически привязывается к новому коду. Клиенты, которые предпочитают использовать старую версию, могут по-прежнему получить доступ к ней, используя полный путь к вложенному пространству имен, содержащему данный код.

Ключевое слово inline должно применяться к первому объявлению пространства имен в единице компиляции.

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

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

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

Вы можете создать явное пространство имен, но не присвоить ему имя.

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

Источник

Добавить комментарий

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