Главная » Статьи » Мои статьи » С++ для начинающих |
Предположим, что мы хотим предоставить в общее пользование
наш класс Array,
разработанный в предыдущих примерах. Однако не мы одни занимались этой
проблемой; возможно, кем-то где-то, скажем, в одном из подразделений компании
Intel был создан одноименный класс. Из-за того что имена этих классов
совпадают, потенциальные пользователи не могут задействовать оба класса
одновременно, они должны выбрать один из них. Эта проблема решается добавлением
к имени класса некоторой строки, идентифицирующей его разработчиков,
скажем, class Cplusplus_Primer_Third_Edition_Array { ... }; Конечно, это тоже не гарантирует уникальность имени, но с
большой вероятностью избавит пользователя от данной проблемы. Как, однако,
неудобно пользоваться столь длинными именами! Стандарт С++ предлагает для решения проблемы совпадения имен механизм, называемый пространством имен. Каждый производитель программного обеспечения может заключить свои классы, функции и другие объекты в свое собственное пространство имен. Вот как выглядит, например, объявление нашего класса Array:
} Ключевое слово namespace
задает пространство имен, определяющее видимость нашего класса и названное в
данном случае Cplusplus_Primer_3E. Предположим,
что у нас есть классы от других разработчиков, помещенные в другие пространства
имен: namespace IBM_Canada_Laboratory { template <class elemType> class Array { ... }; class Matrix { ... }; } namespace Disney_Feature_Animation { class Point { ... }; template <class elemType> class Array { ... }; } По умолчанию в программе видны объекты,
объявленные без явного указания пространства имен; они относятся к глобальному пространству имен. Для того
чтобы обратиться к объекту из другого пространства, нужно использовать его квалифицированное имя, которое состоит
из идентификатора пространства имен и идентификатора объекта, разделенных
оператором разрешения области видимости (::).
Вот как выглядят обращения к объектам приведенных выше примеров:
IBM_Canada_Laboratory::Matrix mat; Disney_Feature_Animation::Point origin(5000,5000); Для удобства использования можно назначать псевдонимы пространствам имен. Псевдоним
выбирают коротким и легким для запоминания. Например: //
псевдонимы namespace LIB = IBM_Canada_Laboratory; namespace DFA = Disney_Feature_Animation; int main() { LIB::Array<int> ia(1024); } Псевдонимы употребляются и для того, чтобы скрыть
использование пространств имен. Заменив псевдоним, мы можем сменить набор
задействованных функций и классов, причем во всем остальном код программы
останется таким же. Исправив только одну строчку в приведенном выше примере, мы
получим определение уже совсем другого массива: namespace LIB = Cplusplus_Primer_3E; int main() { LIB::Array<int> ia(1024); } Конечно, чтобы это стало возможным, необходимо точное
совпадение интерфейсов классов и функций, объявленных в этих пространствах
имен. Представим, что класс Array из Disney_Feature_Animation
не имеет конструктора с одним параметром – размером. Тогда следующий код
вызовет ошибку: namespace LIB = Disney_Feature_Animation; int main() { LIB::Array<int> ia(1024); } Еще более удобным является способ использования простого, неквалифицированного имени для обращения к объектам, определенным в некотором пространстве имен. Для этого существует директива using: #include "IBM_Canada_Laboratory.h" using namespace IBM_Canada_Laboratory; int main() { // IBM_Canada_Laboratory::Matrix Matrix mat(4,4); // IBM_Canada_Laboratory::Array Array<int> ia(1024); // ... } Пространство имен IBM_Canada_Laboratory становится видимым в программе. Можно сделать видимым не все пространство, а отдельные имена внутри него (селективная директива using): #include "IBM_Canada_Laboratory.h" using namespace IBM_Canada_Laboratory::Matrix; //
видимым становится только Matrix int main() { // IBM_Canada_Laboratory::Matrix Matrix mat(4,4); // Ошибка: IBM_Canada_Laboratory::Array
невидим Array<int> ia(1024); // ... } Как мы уже упоминали, все компоненты стандартной библиотеки
С++ объявлены внутри пространства имен std. Поэтому простого включения
заголовочного файла недостаточно, чтобы напрямую пользоваться стандартными
функциями и классами: #include <string> //
ошибка: string невидим string
current_chapter = "Обзор С++"; Необходимо
использовать директиву using: #include <string> using namespace std; //
Ok: видим string string current_chapter = "Обзор
С++"; Заметим, однако, что таким образом мы
возвращаемся к проблеме "засорения” глобального пространства имен, ради решения
которой и был создан механизм именованных пространств. Поэтому лучше
использовать либо квалифицированное имя:
//
правильно: квалифицированное имя std::string
current_chapter = "Обзор С++"; либо
селективную директиву using: #include <string> using namespace std::string; //
Ok: string видим string current_chapter = "Обзор
С++"; Мы рекомендуем пользоваться последним способом. В большинстве примеров этой книги директивы пространств имен
были опущены. Это сделано ради сокращения размера кода, а также потому, что
большинство примеров были скомпилированы компилятором, не поддерживающим пространства
имен – достаточно недавнего нововведения С++. (Детали применения
using-объявлений при работе с стандартной библиотекой С++ обсуждаются в разделе
8.6.) В нижеследующих главах мы создадим еще четыре класса: String,
Stack,
List
и модификацию Stack. Все они будут заключены в одно
пространство имен – Cplusplus_Primer_3E. (Более подробно
работа с пространствами имен рассматривается в главе 8.) Упражнение 2.21 Дано пространство имен
template <class elemType> class Array { ... }; template <class EType> void print (Array< EType > ); class String { ... } template <class ListType> class List { ... }; } и текст программы:
const int size = 1024; Array<String> as (size); List<int> il (size); // ... Array<String> *pas = new Array<String>(as); List<int> *pil = new List<int>(il); print (*pas); } Программа не компилируется, поскольку объявления
используемых классов заключены в пространство имен Exercise.
Модифицируйте код программы, используя (a) квалифицированные имена (b) селективную директиву using (c) механизм псевдонимов (d) директиву using | ||||||
Просмотров: 3611 | Комментарии: 7 | | |
Всего комментариев: 1 | ||
| ||