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

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


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

Обратите внимание, что using-директива не объявляет имена в той области действия, где употребляется:

namespace X { int а; int b; ...

using namespace X; сделать доступными все имена из х using X::b; объявить локальный синоним для Х::Ь

int il = :.&; ошибка: в глобальной области а не объявлена int i2 = ::b; правильно: будет найден локальный синоним Х:;Ь

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

17.4.5.3. Перегрузка

Самым запутанным аспектом предложения о пространствах имен был вопрос, следует ли разрешать перегрузку имен, объявленных в разных пространствах. Рассмотрим пример:

namespace А { void f(int); ...

using namespace A;

namespace В { void f(char); ...

using namespace B;

void g() {

f(a); вызывается B::f(char);

Пользователь, невнимательно ознакомившийся с пространством имен В, может решить, что будет вызвана А: : f (int). Сложности возникнут и у пользователя, который тщательно изучил программу год назад, но не обратил внимания, что в последней версии в пространство имен В было добавлено объявление f(char).



Однако эта проблема возникает лишь тогда, когда вы сопровождаете программу, в которой предложение using namespace используется дважды для одной и той же области действий - для вновь разрабатываемых продуктов такая практика не рекомендуется. Кроме того, компилятор вполне .может выдать предупреждение о том, что вызов функции разрешен двумя способа.ми за счет объявлений из разных пространств имен, даже если обычные правила перегрузки позволяют выбрать только один вариант. Я рассматриваю using-директивы в основном как средство, применимое только в переходный период; авторы новых программ смогут избежать многих теоретических и некоторых практических затруднений, если будут по возможности употреблять квалифицированные имена и using-объявления.

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

старый код:

void f(int); из A.h ...

void f(char); из B.h ...

void g() {

f(a); вызывается f из B.h

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

17.4.5.4. Вложенные пространства имен

Одно из очевидных применений пространства имен - помешение в него полного набора объявлений и определений:

namespace X {

все мои объявления

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

void h();

namespace х { void g(); ...



namespace Y { void f(); void ff0; . . .

. . .

Применимы обычные правила областей действия и квалификации:

void X::Y::ff() {

f О ; gO ; h()

void X::g( {

fO; Y: :f 0 ;

ошибка: в X нет f()

void h( {

f();

: f () ; : f () ; :Y::f0

ошибка: нет глобальной f() ошибка: нет глобального Y ошибка: в X нет f()

17.4.5.5. Пространства имен открыты

Пространство имен открыто в том смысле, что его можно составлять из нескольких объявлений, расположенных в разных местах. Например:

namespace А { int f();

сейчас в А есть член f(

namespace А { int g() ;

а сейчас в А есть члены f() и g()

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

мой заголовочный файл: extern void f() ; моя функция ...



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

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