Программирование >>  Полиморфизм без виртуальных функций в с++ 

1 ... 131 132 133 [ 134 ] 135 136 137 ... 144


новый порядок следования новая функция

namespace release2 { ... class X {

Impl::Xrep* p; public:

virtual void f2() = 0 virtual void f3() = 0 virtual void f1() = 0 . . .

...

Старый код пользуется версией releasel, новый - версией release2. При этом оба кода работают и не вступают в конфликт. Заголовочные файлы для версий releasel и release2 различаются, так что для обеспечения минимальной функциональности пользователю нужен только один # include. Чтобы облегчить переход на новую версию, можно воспользоваться псевдонимом пространства имен для локализации последствий изменения версии. Всего один файл

lib.h:

namespace lib = releasel; ...

может инкапсулировать все зависимости от версии и использоваться всюду: #include lib.h

class XX : public lib::X { ...

При переходе на новую версию достаточно изменить лишь одну строку:

lib.h:

namespace lib = release2; ...

Такое изменение делается лишь тогда, когда появились основательные причины перейти к версии release2, и нашлось время, чтобы перекомпилировать программу и разобраться с возможными несовместимостями между обеими версиями на уровне исходных текстов.

77.4.5. Технические детали

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

17.4.5.1. Удобство и безопасность

Using-объявление добавляет имена в локальную область действия. Using-директива этого не делает, она лишь обеспечивает доступность имен. Например:



namespace X ( int i, j, к;

int к;

void {

in us i+

j + k+

t i = 0;

ing namespace X;

+: + +

k++; :k++;

делает доступными имена из X

локальное i

X::j

ошибка: Х::к или глобальное к?

глобальное к

к из X

void f2()

int i =

using X

ошибка: i дважды объявлена

using X

: j;

using X

скрывает глобальное к

i + + ;

j++;

X: :

k++;

X: :

Тем самым сохраняется важное свойство: локально объявленное имя (введенное либо с помощью обычного, либо с помощью using-объявления) скрывает нелокальные объявления того же имени, и любая некорректная перегрузка имени обнаруживается в точке объявления.

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

С другой стороны, нелокальные имена видимы в контексте, где были объявлены, и трактуются так же, как любые другие нелокальные имена. В частности, ошибки, связанные с using-директивой, обнаруживаются только в точке использования. Это защищает программиста от сообщений компилятора о потенциальных ошибках. Например:

namespace А { int х;

namespace В { int х;



void fO {

using namespace A;

using namespace B; правильно: здесь ошибки нет

А::х++; правильно

В::х++; правильно

Х++; ошибка: А::х или В::х?

17.4.5.2. Глобальная область действия

С появлением пространств имен глобальная область действия стала лишь еще одним пространством имен. Особенность глобального пространства имен состоит только в том, что его имя не обязательно явно квалифицировать. Запись : : f означает f объявлено в глобальном пространстве имен , тогда как X: : f означает f объявлено в пространстве имен X . Рассмотри.м пример:

int а;

void fO {

int а = 0;

а++; локальное а

::а++; глобальное а

Если по.местить этот код в пространство имён и добавить еще одну переменную а, получим:

int а;

namespace X { int а;

void f() {

int a = 0;

a++; локальное a

X: :a++,- X: :a

::a++; X::a или глобальное a? - глобальное a

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



1 ... 131 132 133 [ 134 ] 135 136 137 ... 144

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика