Мегаобучалка Главная | О нас | Обратная связь


Пространства имен и модули



2016-01-26 401 Обсуждений (0)
Пространства имен и модули 0.00 из 5.00 0 оценок




 

Системы имеют подсистемы, которые в свою очередь состоят из подсистем и так до бесконечности — именно поэтому мы всегда движемся сверху вниз.

— Алан Перлис (Alan Perlis)

 

Пространство имен — очень важный инструмент для управления именами и снижения количества коллизий имен. То же относится и к модулям, которые, помимо этого, представляют собой инструментарий для работы с версиями. Мы определим модуль как отдельный компонент программы, содержащий тесно связанные между собой ее элементы (см. рекомендацию 5) и поддерживаемый одним и тем же программистом или группой; обычно модуль всегда компилируется одним и тем же компилятором с использованием одних и тех же опций. Модули имеются на разных уровнях детализации в широком диапазоне размеров. С одной стороны, модуль может быть минимального размера, представляя собой отдельный объектный файл, содержащий только один класс; с другой стороны, он может быть, например, отдельной динамической библиотекой, генерируемой из множества исходных файлов, содержимое которых образует подсистему внутри приложения большего размера или выпускается отдельно. Модуль может даже представлять собой огромную библиотеку, состоящую из множества небольших модулей (статических или динамических библиотек), содержащих тысячи разных типов. Несмотря на то, что такие библиотеки в стандарте С++ не упоминаются, программисты постоянно создают и используют библиотеки, и хорошо продуманная модуляризация является фундаментальной частью успешного управления зависимостями (см., например, рекомендацию 11).

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

В этом разделе мы считаем наиболее значимой рекомендацию 58 — "Храните типы и функции в разных пространствах имен, если только они не предназначены для совместной работы".

 

Храните типы и их свободный интерфейс в одном пространстве имен

 

 

Резюме

 

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

 

Обсуждение

 

Открытый интерфейс класса образуют не только открытые функции-члены, но и функции, не являющиеся членами. Принцип Интерфейса гласит: для класса X все функции (включая функции, не являющиеся членами), которые "упоминают X" и "поставляются вместе с X" в одном и том же пространстве имен, являются логической частью X, поскольку образуют часть интерфейса X (см. рекомендацию 44 и [Sutter00]).

Язык С++ спроектирован с явным учетом Принципа Интерфейса. Причина, по которой в язык добавлен поиск, зависящий от аргумента (argument-dependent lookup — ADL), известный также как поиск Кёнига, заключается в том, чтобы обеспечить коду, использующему объект x типа X, возможность работать с частью его интерфейса, состоящей из функций, не являющихся членами (например, инструкция cout << x использует оператор operator<<, который не является членом класса X) так же легко, как и функции-члены (например, вызов x.f()) не требует выполнения специального поиска, поскольку очевидно, что поиск f выполняется в области видимости X). ADL обеспечивает для свободных функций, которые получают объект X в качестве аргумента и поставляются вместе с определением X ту же простоту использования, что и для функций-членов интерфейса X. Одним из главных мотивов принятия ADL был, в частности, класс std::string (см. [Sutter00]).

Рассмотрим класс X, определенный в пространстве имен N:

class X {

publiс:

void f();

};

 

X operator+(const X&, const X&);

В вызывающей функции обычно пишется код наподобие x3=x1+x2, где x1, x2 и x3 — объекты типа X. Если оператор operator+ объявлен в том же пространстве имен, что и X, никаких проблем не возникает, и такой код отлично работает, поскольку оператор operator+ будет легко найден с помощью ADL.

Если же оператор operator+ не объявлен в том же пространстве имен, что и X, вызывающий код работать не будет. В этом случае имеется два способа заставить его заработать. Первый состоит в использовании явно квалифицированного оператора

x3 = N::operator+(x1, x2);

Грустная картина — невозможность использовать естественный синтаксис оператора, который, собственно, и был главной целью введения перегрузки операторов в язык программирования. Другой способ заставить работать приведенный ранее код — использовать инструкцию using:

using N::operator+;

// или: using namespace N;

x3 = x1 + x2;

Применение using — совершенно нормальная и приемлемая вещь (см. рекомендацию 59), но все проблемы решаются гораздо проще, если автор X изначально поступает корректно и помещает оператор operator+, работающий с объектами X, в то же пространство имен, где находится X.

"Оборотная сторона" этого вопроса рассматривается в рекомендации 58.

 

Примеры

 

Пример 1. Операторы. Операторы работы с потоками operator<< и operator>> для объектов некоторого класса X, вероятно, относятся к наиболее ярким примерам функций, которые вполне очевидно являются частью интерфейса класса X, но при этом всегда представляют собой свободные функции (это обязательное условие, поскольку левый аргумент этих операторов — поток, а не объект X). Та же аргументация применима и к другим операторам, не являющимся членами X. Убедитесь, что ваши операторы находятся в том же пространстве имен, что и класс, с которым они работают. Если у вас есть возможность выбора, лучше делать операторы и все прочие функции не членами и не друзьями класса (см. рекомендацию 44).

Пример 2. Прочие функции. Если автор X предоставляет именованные вспомогательные функции, которые получают в качестве аргументов объекты X, они должны находиться в том же пространстве имен, что и X. В противном случае вызывающий код, использующий объекты X, будет не в состоянии работать с этими именованными функциями без явной квалификации их имен или применения инструкции using.

 

Ссылки

 

[Stroustrup00] §8.2, §10.3.2, §11.2.4 • [Sutter00] §31-34

 



2016-01-26 401 Обсуждений (0)
Пространства имен и модули 0.00 из 5.00 0 оценок









Обсуждение в статье: Пространства имен и модули

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (401)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.009 сек.)