Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП на языке С++.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2 Мб
Скачать
☆

7.1. Пространство имен

Пространства имен предназначены для локализации имен идентификаторов во избежание конфликтов имен. До введения понятия пространств имен все имена используемых в среде программирования С++ переменных, функций и классов находились в одном глобальном пространстве имен и возникало множество конфликтов. Конфликты могут быть двух типов.

  1. Вы работаете в группе разработчиков и ввели в своей программе класс Dog. Кому-то из ваших коллег тоже понадобилось ввести класс Dog. Само по себе это не так уж страшно, поскольку если вы попытаетесь объединить ваши программы, то компилятор обнаружит ошибку дублирования имен. Гораздо хуже, если конфликт имен возникает из-за наличия одинакового имени где-нибудь внутри библиотеки классов, которую вы купили для использования в вашем проекте. Особенно вероятна такая ситуация, когда в одной и той же программе используются библиотеки функций и классов разных производителей. Если библиотеки поставляются без исходных текстов, а только с заголовочными файлами, вы окажетесь в очень затруднительной ситуации.

  2. Конфликт второго рода связан с сокрытием переменных. Например, имеется следующий текст:

void main()

{int x;

…

{int x;

…}

…}

В момент входа во внутренний блок локальная переменная х скрывает внешнюю х из main().

Сокрытие переменных в С++ является, на первый взгляд, достоинством языка, а не недостатком. Оно облегчает инкапсуляцию. С другой стороны, также нетрудно вообразить случай, когда программист полагает, что он использует одну переменную, в то время как в действительности использует совершенно другую. Множество различных определений переменных, вложенных одно в другое и составленных пирамидой благодаря наследованию, может привести к ситуации, когда происходит непреднамеренное сокрытие переменных и в конце концов неправильное их использование.

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

Этим механизмом и является понятие пространств имен и ключевое слово namespace.

Основная форма объявления пространства имен

namespace имя{

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

}

Все, что определено внутри инструкции namespace, находится внутри области видимости данного пространства имен.

Пример 7.1.1.

namespace MyNameSpace{

int i,k;

void myfunc(int j);

class myclass{

int x;

public:

…};

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

…

}

Здесь имена переменных i и k, функции myfunc и класса myclass находятся в области видимости, определенной пространством имен MyNameSpace.

К идентификаторам, объявленным в пространстве имен, внутри этого пространства можно обращаться напрямую. Однако при обращении извне пространства имен к объектам, объявленным внутри этого пространства, следует указывать оператор расширения области видимости

MyNameSpace::i=10;

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

using имя_ пространства_имен::идентификатор;

Такое объявление делает видимым и, соответственно, доступным в текущем пространстве имен указанный идентификатор.

using MyNameSpace::i;

i=10;

Для того чтобы сделать доступными в текущем пространстве имен все имена из заданного пространства имен, необходимо использовать директиву using.

using namespace имя_ пространства_имен;

using namespace MyNameSpace;

i=10;

k=5;

myclass ob;

Имеется возможность объявить более одного пространства имен с одним и тем же именем. Это позволяет разделить пространство имен на несколько файлов или внутри одного файла.

namespace NS{

int i;

…}

…

namespace NS{

int j;

...}

Здесь пространство имен NS разделено на две части. Несмотря на это, содержимое каждой части по-прежнему остается в одном и том же пространстве имен NS.

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

Пространство имен может быть объявлено без имени

namespace{

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

}

Это позволяет создавать идентификаторы, являющиеся уникальными внутри некоторого файла. Вне файла, содержащего безымянное пространство имен, члены этого пространства невидимы.

Одна из проблем с namespace состоит в том, что короткие названия пространств имен могут войти в конфликт друг с другом. С другой стороны, весьма неудобно применять длинные имена.

Решение данной проблемы состоит в использовании псевдонимов для namespace.

namespace Lib=Foundation_library_classes;

Перегрузка компонентных функций.

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

Пример 7.1.2.

Файл lib.h.

#ifndef LIB_H

#define LIB_H

namespace Other_lib

{

#include<head1.h>

#include< head2.h >

#include< head3.h >

}

namespace LIB=Other_lib;

#endif

//использование другой библиотеки

#include<lib.h>

…

LIB::func();

Для небольших и средних по объему программ маловероятна необходимость создания своих пространств имен. Однако, если вы собираетесь создавать библиотеки функций или классов, предназначенных для многократного использования, или хотите гарантировать своим программам широкую переносимость, вам следует рассмотреть возможность размещения своих кодов внутри некоторого пространства имен. В Microsoft Visual C++ библиотека классов определена в пространстве имен std.

using namespace std;