Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
84
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

С++ для начинающих

411

 

 

// ---- primer.C ----

 

 

 

 

 

 

#include "primer.h"

 

 

 

namespace cplusplus_primer {

 

 

 

// определения функций

 

 

 

void inverse( matrix & )

 

 

 

{ /* ... */ }

matrix &m2 )

 

 

matrix operator+ ( const matrix &ml, const

 

 

{ /" ... */ }

 

 

 

// определения объектов

 

 

 

bool error_state = false;

 

 

 

}

 

 

 

 

 

 

 

Для объявления объекта без его определения используется ключевое слово extern, как и в случае такого объявления в глобальной области видимости.

8.5.6. Безымянные пространства имен

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

Предположим, мы хотим реализовать набор функций для сортировки вектора типа

// ----- SortLib.h -----

void quickSort( double *, double * ); void bubbleSort( double *, double * ); void mergeSort( double *, double * );

double:

void heapSort( double *, double * );

Все они используют одну и ту же функцию swap() для того, чтобы менять местами элементы вектора. Однако она не должна быть видна во всей программе, поскольку нужна только четырем названным функциям. Локализуем ее в файле SortLib.C.

// -----

SortLib.C -----

*/ }

 

void swap( double *dl, double *d2 ) { /* ...

 

// только эти функции используют swap()

 

*/ }

void quickSort( double *d1, double *d2 ) { /* ...

void bubbleSort( double *d1, double *d2 ) { /* ...

*/ }

void mergeSort( double *d1, double *d2 ) { /* ...

*/ }

Приведенный код не дает желаемого результата. Как вы думаете, почему? void heapSort( double *d1, double *d2 ) { /* ... */ }

С++ для начинающих

412

Хотя функция swap() определена в файле SortLib.C и не появляется в заголовочном

 

файле SortLib.h, где содержится описание интерфейса библиотеки сортировки, она

 

объявлена в глобальной области видимости. Следовательно, это имя является

 

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

 

Язык С++ предоставляет возможность использования безымянного пространства имен

 

для объявления сущности, локальной по отношению к файлу. Определение такого

 

пространства начинается ключевым словом namespace. Очевидно, что никакого имени за

 

этим словом нет, а сразу же идет блок в фигурных скобках, содержащий различные

 

 

// ----- 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 можно переписать на С,

//SortLib.C

//swap() невидима для других файлов программы

static void swap( double *d1, double *d2 ) { /* ... */ }

сохранив свойства swap():