С++ для начинающих




Using-директивы - часть 3


Во-вторых, ошибки неоднозначности, вызванные применением using-директивы, обнаруживают себя при реальном обращении к такому имени, а не при встрече в тексте самой этой директивы. Например, переменная bj, член пространства blib, выглядит для manip() как объявленная в глобальной области видимости, вне blip. Однако в глобальной области уже есть такая переменная. Возникает неоднозначность имени bj в функции manip(): оно относится и к глобальной переменной, и к члену пространства blip. Ошибка проявляется только при упоминании bj в функции manip(). Если бы это имя вообще не использовалось в manip(), коллизия не проявилась бы.

В-третьих, using-директива не затрагивает употребление квалифицированных имен. Когда в manip() упоминается ::bj, имеется в виду переменная из глобальной области видимости, а blip::bj обозначает переменную из пространства имен blip.

И наконец члены пространства blip выглядят для функции manip() так, как будто они объявлены в глобальной области видимости. Это означает, что локальные объявления внутри manip() могут скрывать имена членов пространства blip. Локальная переменная bk скрывает blip::bk. Ссылка на bk внутри manip() не является неоднозначной – речь идет о локальной переменной.

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

namespace cplusplus_primer {

    class matrix { };

    // прочие вещи ...

}

namespace DisneyFeatureAnimation {

    class matrix { };

    // здесь тоже ...

using namespace cplusplus_primer;

using namespace DisneyFeatureAnimation;

matrix m; //ошибка, неоднозначность:

// cplusplus_primer::matrix или DisneyFeatureAnimation::matrix?

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

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




Содержание  Назад  Вперед