|
Программирование >> Полиморфизм без виртуальных функций в с++
Думается, что применять глобальные имена станут значительно реже. Правила для пространств имен специально были составлены так, чтобы не давать никаких преимуществ ленивым программистам по сравнению с теми, кто сознательно стремится не засорять глобальную область действия. Обратите внимание, что 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() ; моя функция ...
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |