Программирование >>  Инициализация объектов класса, структура 

1 ... 136 137 138 [ 139 ] 140 141 142 ... 395


#include primer.h using cplusplus primer::matrix; using cplusplus primer::inverse;

using-объявления позволяют использовать имена matrix и inverse без спецификации void func( matrix &m ) {

...

verse

inverse( m ); return m;

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

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

#include pnmer.h

using-директива: все членах cplusplus primer становятся видимыми

using namespace cplusplus primer;

имена matrix и inverse можно использовать без спецификации

void func( matrix &

void func( matrix &m ) / /

inverse( m ); return m;

Например, предыдущий фрагмент кода может быть переписан так:

Using-директива делает имена членов пространства имен видим1ми за его пределами, в том месте, где она использована. Например, приведенная using-директива создает иллюзию того, что все члены cplusplus primer объявлены в глобальной области видимости перед определением func() . При этом члены пространства имен не получают

namespace A { int i, j;

локальных псевдонимов, а как бы перемещаются в новую область видимости. Код

выглядит как



namespace blip {

int bi = 16, bj = 15, bk = 23;

прочие объявления

int bj = 0;

void manip() {

using namespace blip; using-директива -

коллизия имен ::bj and blip::bj обнаруживается только при использовании bj ++bi; blip::bi == 17

++bj; ошибка: неоднозначность

глобальная bj blip::bj?

++::bj; правильно: глобальная bj == 1

++blip::bj; правильно: blip::bj == 16

int bk = 97; локальная bk скрает blip::bk

++bk; локальная bk == 98

пространства имен).

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

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

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

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

int i, j;

для фрагмента программы, содержащего в области видимости следующую using-директиву:

using namespace A;

Рассмотрим пример, позволяющий подчеркнуть разницу между using-объявлением (которое сохраняет пространство имен, но создает ассоциированные с его членами локальные синоним:) и 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-директивами, чтобы избежать засорения глобального пространства имен в своей программе.

8.6.4. Стандартное пространство имен std

Все компоненты стандартной библиотеки С++ находятся в пространстве имен std. Каждая функция, объект и шаблон класса, объявленные в стандартном заголовочном файле, таком, как <vector> или <iostreami>, принадлежат к этому пространству.

Если все компоненты библиотеки объявлены в std, то какая ошибка допущена в данном примере:

переменная bk скрывает blip::bk. Ссылка на bk внутри manip() не является неоднозначной - речь идет о локальной переменной.

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



1 ... 136 137 138 [ 139 ] 140 141 142 ... 395

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