namespace CounterNameSpace {
int upperbound;
int lowerbound;
class counter {
int count;
public:
counter (int n) {
if(n <= upperbound) count = n;
else count = upperbound;
}
void reset(int n) {
if(n <= upperbound) count = n;
}
int run() {
if(count > lowerbound) return count--;
else return lowerbound;
}
};
}
int main()
{
/* Используется только член upperbound из пространства имен CounterNameSpace. */
using CounterNameSpace::upperbound;
/* Теперь для установки значения переменной upperbound не нужно указывать пространство имен. */
upperbound = 100;
/* Но при обращении к переменной lowerbound и другим объектам по-прежнему необходимо указывать пространство имен. */
CounterNameSpace::lowerbound = 0;
CounterNameSpace::counter ob1(10);
int i;
do {
i = ob1.run();
cout << i << " ";
}while(i > CounterNameSpace::lowerbound);
cout. << endl;
/* Теперь используем все пространство имен CounterNameSpace. */
using namespace CounterNameSpace;
counter ob2(20);
do {
i = ob2.run();
cout << i << " ";
}while(i > lowerbound);
cout << endl;
ob2.reset(100);
lowerbound = 90;
do {
i = ob2.run();
cout << i << " ";
}while(i > lowerbound);
return 0;
}
Эта программа иллюстрирует еще один важный момент. Использование одного пространства имен не переопределяет другое. Если некоторое пространство имен становится "видимым", это значит, что оно просто добавляет свои имена к именам других, уже действующих пространств. Поэтому к концу этой программы к глобальному пространству имен добавились и std, и CounterNameSpace.
Неименованное пространство имен ограничивает идентификаторы рамками файла, в котором они объявлены.
Существует неименованное пространство имен специального типа, которое позволяет создавать идентификаторы, уникальные для данного файла. Общий формат его объявления выглядит так.
namespace {
// объявления
}
Неименованные пространства имен позволяют устанавливать уникальные идентификаторы, которые известны только в области видимости одного файла. Другими словами, члены файла, который содержит неименованное пространство имен, можно использовать напрямую, без уточняющего префикса. Но вне файла эти идентификаторы неизвестны.
Как упоминалось выше в этой книге, использование модификатора типа static также позволяет ограничить область видимости глобального пространства имен файлом, в котором он объявлен. Например, рассмотрим следующие два файла, которые являются частью одной и той же программы.
Поскольку переменная k определена в файле One, ее и можно использовать в файле One. В файле Two переменная k определена как внешняя (extern-переменная), а это значит, что ее имя и тип известны, но сама переменная k в действительности не определена. Когда эти два файла будут скомпонованы, попытка использовать переменную k в файле Two приведет к возникновению ошибки, поскольку в нем нет определения для переменной k. Тот факт, что k объявлена static-переменной в файле One, означает, что ее область видимости ограничивается этим файлом, и поэтому она недоступна для файла Two.