Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование / ЛАБ.РАБОТЫ_С++_2012 / ЛАБ_14 / Задачи к лаб.раб.14_ПРОСТРАНСТВА ИМЕН

.doc
Скачиваний:
52
Добавлен:
02.02.2015
Размер:
199.68 Кб
Скачать

ПРОСТРАНСТВА ИМЕН

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

Для стандартной библиотеки закреплено свое имя пространства имен std.

Пространство имен ограничивает область видимости. Размещенные в этой области имена вне этой области невидимы (недостижимы ). Описание пространства имен можно представит в виде специальной функции. Используя грамматику языка Бэкуса-Наури эту функцию можно представить в виде (имена пространств имен будем обозначать (называть) ns1, ns2, …, nsi):

[ using] namespace [ имя пространства ] [ :: имя функц/переменной][, имя функ/переем. …]

[ {

// Объявления

} ]]

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

1) namespace { // объявления } – безымянное пространство имен, видимость которых ограничена файлом.

2) namespace ns1 { // объявления } - именное пространство имен

3) namespace ns1 { // объявления } – совокупность отдельных

namespace ns2 { // объявления } пространств имен

- - - - - - - - - - - - - - - - - - - - - - - - - -

namespace nsi { // объявления }

4) namespace ns1 - вложенные пространства имен

{ // объявления

namespace ns2

{ // объявления

- - - - - - - - - - - - -

namespace nsi

{ // объявления

}

}

}

5)using namespace std;- полное пространство имен, применяемых в библиотеке std.

6) using std :: отдельное имя из библиотеки std; // cout, cin, left, hex, showpos и др..

7) std :: отдельное имя - имя, применяемое в библиотеке std.

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

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

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

#include <iostream>

int f()

{ int if, jf, kf;

if = jf = kf = 3;

}

int main ()

{ int im, jm, km;

cout<<” if= ”<<if<<” ig= ”<<ig<<” im= ”<<im<<” “<<”\n”;

}

int g()

{ int ig, jg, kg;

ig = jg = kg =5;

}

Остановимся подробнее на применении описанных структур.

1) Приведенный ниже текст программы (пример 1) демонстрирует работу с применением безымянного пространства имен. В тексте программы не используется пространство имен стандартной библиотеки std. Для этого закомментированы следующие строки

// #include <iostream>

// using namespace std;

// cout<<”\n mi= ”<<mi<<”\n”;

Отмечено, что по умолчанию #include “stdafx.h” включает библиотеку <stdio.h>

Для работы программы следует удалить комментарии /* 1 1*/ и оставить везде комментарии // 2 . При этом работает механизм безымянного пространства имен.

Пример 1

2) Имя пространства имен является квалификатором, который используется для сопровождения отдельных имен, объявленных в выделенном пространстве имен. Ниже приведен текст программы, рассмотренный в примере 1, но с применением имени пространства имен ns1.

Полученный текст программы представлен в виде двух примеров:

    • примера 2_1 - с пространством имен, не включающим функции f() и g();

    • примера 2_2 - с пространством имен, включающим функции f() и g().

Сравнение двух этих программ наглядно демонстрирует механизм описания переменных с применением названий пространства имен.

Пример 2_1_(2)

Пример 2_2_(3)

3) При рассмотрении нескольких отдельных пространств имен рассматривается пример предыдущей задачи с двумя пространствами имен ns1 и ns2 и с разделением одного пространства имен (например ns1) на несколько частей в одном файле.

В примере 3_1 демонстрируется применение двух непересекающихся пространств имен ns1 и ns2 и организация добавления этих имен к соответствующим именам в тексте программы (ns1 ->f(), ns2 ->mi, g()).

Пример 3_1_(4)

Разделение одного пространства имен на несколько частей с одним именем даже в одном файле показано в примере 3_2. Из сравнения текста программы примера 3_1 и текста программы примера 3_2 видно, что в последнем случае везде имя ns2 было заменено на имя ns1.

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

Пример 3_2_(5)

4) Различные пространства имен могут быть вложены друг в друга. Ниже рассматривается текст программы, в котором пространство имен ns2 вложено в пространство имен ns1. Как видно, в этом случае для обращения к именам, относящихся к вложенным пространствам имен, следует добавлять цепочку имен пространств имен, начиная с внешнего к внутреннему. В приведенном примере это показано в операторе

ns1::ns2::mi = ns1::f() * ns1::ns2::g();

Ниже приведен текст программы ( Пример 4 ), демонстрирующей сказанное

Пример 4_(6)

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

mi = f() * g();

С учетом директивы using описание пространства имен может иметь виды

using namespace ns;

using ns :: name;

Описание using namespace ns; включает имя пространства имен ns и обеспечивает обращение ко всем именам в тексте программы без применения квалификаторов.

Второе описание using ns :: name; выделяет в пространстве имен ns только одно имя в тексте программы ( здесь name), при обращении к которому обходятся без квалификатора.

В тексте программы в главной функции _tmain() показаны три строки, впереди которых расположен текст /*/ 1 */. Эти строки не закомментированы и показывают работу с описанием пространства имен в виде using namespace ns;. Следующие три стоки впереди имеют текст // 2 */ и являются закомментированными. Они демонстрируют работу с описанием using ns::name. Как видно, для перевода не комментированных строк в комментируемые и наоборот следует выполнить /*/ 1*/ -> // * 1/ или // 2 */ -> /*/ 2 */.

Пояснения: f() = fi + fj + fk = 9; g() = gi + gj + gk = 15; mi = 195.

Пример 5 _(7)_(в программе рассматриваются одновременно структуры 5) и 6))

Пространство имен std зарезервировано за стандартной библиотекой. Если стандартную библиотеку не включать в глобальное пространство имен, то в тексте программы придется писать, например, std::cout<< “ ”<<x<<”\n”; std::cin>>x; и так далее. Для ограничения использования глобального пространства можно применить такую структуру программы:

#include <iostream>

using std::cout; // без using namespace std;

using std::cin; // и другое

int main()

{ cout<<” “;

cin>>x;

-- - - -

}

Составить самостоятельно примеры (8) программ с применением различных форм использования using.

9