Программирование >>  Инициализация объектов класса, структура 

1 ... 130 131 132 [ 133 ] 134 135 136 ... 395


ps.get()->assign( Danny ) ;

и почему?

ps->assign( Danny );

8.5. Определения пространства имен А

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

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

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

class cplusplus primer matrix { ... };

префикса употребляется определенная последовательность символов. Например:

void inverse( cplusplus primer matrix & );

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

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

namespace cplusplus primer { class matrix { /*...*/ };

void inverse ( matrix & );

вынести используемые в библиотеке имена из глобальной области видимости:

Пусть мы имеем:

auto ptr< string > ps( new string( Daniel ) );

В чем разница между этими двумя вызовами assign() ?Какой их них предпочтительнее



void func( cplusplus primer::matrix &m ) {

...

cplusplus primer::inverse(m); return m;

имени:

Если в другом пользовательском пространстве имен (скажем, DisneyFeatureAnimiation) также существует класс matrix и функция inverse() и мы хотим использовать этот класс вместо объявленного в пространстве cplusplus primer, то функцию func()

void func( DisneyFeatureAnimation::matrix &m ) {

...

DisneyFeatureAnimation::inverse(m); return m;

нужно модифицировать следующим образом:

Конечно, каждый раз указывать специфицированные имена типа

namespace name::member name

неудобно. Поэтому существуют механизмы, позволяющие облегчить использование пространств имен в программах. Это псевдонимы пространств имен, using-объявления и using-директивы. (Mi рассмотрим их в разделе 8.6.)

cplusplus primer является пользовательским пространством имен (в отличие от глобального пространства, которое неявно подразумевается и существует в любой программе).

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

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

Имя члена пространства имен автоматически дополняется, или квалифицируется, именем этого пространства. Например, имя класса matrix, объявленное в пространстве cplusplus primer, становится cplusplus primer: :miatrix, а имя функции inverse() превращается в cplusplus primer::inverse() .

Члены cplusplus primer могут использоваться в программе с помощью спецификации



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

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

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

Помещая объявление в пользовательское пространство, мы не меняем его семантики. Единственное отличие состоит в том, что имена, вводим1е такими объявлениями,

namespace cplusplus primer {

class matrix { /* ... */ }; void inverse ( matrix & );

matrix operator+ ( const matrix &ml, const matrix &m2 ) {/* ... */ }

const double pi = 3.1416;

включают в себя имя пространства, внутри которого они объявлены. Например:

Именем класса, объявленного в пространстве cplusplus primer, будет

cplusplus primer::matrix Именем функции

cplusplus primer::inverse() Именем константы

cplusplus primer::pi

Имя класса, функции или константы расширяется именем пространства, в котором они объявлен!. Такие имена называют квалифицированными.

Определение пространства имен не обязательно должно быть непрерывным. Например, предыдущее пространство могло быть определено таким образом:



1 ... 130 131 132 [ 133 ] 134 135 136 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика