// ----- SortLib.C -----
namespace {
void swap( double *dl, double *d2 ) { /* ... */ }
}
// определения функций сортировки не изменяются
Функция swap() видна только в файле SortLib.C. Если в другом файле в безымянном пространстве имен содержится определение swap(), то это другая функция. Наличие двух функций swap() не является ошибкой, поскольку они различны. Безымянные пространства имен отличаются от прочих: определение такого пространства локально для одного файла и не может размещаться в нескольких.
Имя swap() может употребляться в неквалифицированной форме в файле SortLib.C после определения безымянного пространства. Оператор разрешения области видимости для ссылки на его члены не нужен.
void quickSort( double *d1, double *d2 ) {
// ...
double* elem = d1;
// ...
// ссылка на член безымянного пространства имен swap()
swap( d1, elem );
// ...
}
Члены безымянного пространства имен относятся к сущностям программы. Поэтому функция swap() может быть вызвана во время выполнения. Однако имена этих членов видны только внутри одного файла.
До того как в стандарте С++ появилось понятие пространства имен, наиболее удачным решением проблемы локализации было использование ключевого слова static, унаследованного из С. Член безымянного пространства имеет свойства, аналогичные глобальной сущности, объявленной как static. В языке С такая сущность невидима вне файла, в котором объявлена. Например, текст из SortLib.C можно переписать на С, сохранив свойства swap():
// SortLib.C
// swap() невидима для других файлов программы
static void swap( double *d1, double *d2 ) { /* ... */ }
// определения функций сортировки такие же, как и раньше
Во многих программах на С++ используются объявления с ключевым словом static. Предполагается, что они должны быть заменены безымянными пространствами имен по мере того, как все большее число компиляторов начнет поддерживать это понятие.
Зачем нужно определять собственное пространство имен в программе?
Имеется следующее объявление operator*(), члена вложенного пространства имен cplusplus_primer::MatrixLib:
namespace cplusplus_primer {
namespace MatrixLib {
class matrix { /*...*/ };
matrix operator* ( const matrix , const matrix );
// ...
}
}
Как определить эту функцию в глобальной области видимости? Напишите только прототип.
Объясните, зачем нужны безымянные пространства имен.
8.6. Использование членов пространства имен А
Использование квалифицированных имен при каждом обращении к членам пространств может стать обременительным, особенно если имена пространств достаточно длинны. Если бы удалось сделать их короче, то такие имена проще было бы читать и набивать. Однако употребление коротких имен увеличивает риск их совпадения с другими, поэтому желательно, чтобы в библиотеках применялись пространства с длинными именами.
К счастью, существуют механизмы, облегчающие использование членов пространств имен в программах. Псевдонимы пространства имен, using-объявления и using-директивы помогают преодолеть неудобства работы с очень длинными именами.
8.6.1. Псевдонимы пространства имен
Псевдоним пространства имен используется для задания короткого синонима имени пространства. Например, длинное имя
namespace International_Business_Machines
{ /* ... */ }
может быть ассоциировано с более коротким синонимом:
namespace IBM = International_Business_Machines;
Объявление псевдонима начинается ключевым словом namespace, за которым следует короткий псевдоним, а за ним – знак равенства и исходное полное имя пространства. Если полное имя не соответствует никакому известному пространству, это ошибка.
Псевдоним может относиться и к вложенному пространству имен. Вспомним слишком длинное определение функции func() выше:
#include "primer.h"
// трудно читать!
void func( cplusplus_primer::MatrixLib::matrix m )
{
// ...
cplusplLis_primer::MatrixLib::inverse( m );
return m;
}
Разрешается задать псевдоним для обозначения вложенного cplusplLis_primer::MatrixLib, сделав определение функции более удобным для восприятия:
#include "primer.h"
// более короткий псевдоним