(f) auto_ptrint p5(p2.get());

(9) auto_ptrint p6(p2.release());

(h) auto_ptrint p7(p2);

Упражнение 8.9

Объясните разницу между следующими инструкциями:

int *pi0 = p2.get();

int *pi1 = p2.release() ;

Для каких случаев более приемлем тот или иной вызов?

Упражнение 8.10

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

auto_ptr string ps( new string( "Daniel" ) );

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

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

ps-assign( "Danny" );

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

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

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

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

class cplusplus_primer_matrix { ... };

void inverse( cplusplus_primer_matrix );

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

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

namespace cplusplus_primer {

class matrix { /*...*/ };

void inverse ( matrix );

}

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

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

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

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

cplusplus_primer::inverse().

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

void func( cplusplus_primer::matrix m )

{

// ...

cplusplus_primer::inverse(m);

return m;

}

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

void func( DisneyFeatureAnimation::matrix m )

{

// ...

DisneyFeatureAnimation::inverse(m);

return m;

}

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

namespace_name::member_name

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

<p>8.5.1. Определения пространства имен</p>
Перейти на страницу:

Похожие книги