57. Храните типы и их свободный интерфейс в одном пространстве имен
57. Храните типы и их свободный интерфейс в одном пространстве имен
Резюме
Функции, не являющиеся членами и разработанные как часть интерфейса класса 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
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
58. Храните типы и функции в разных пространствах имен, если только они не предназначены для совместной работы
58. Храните типы и функции в разных пространствах имен, если только они не предназначены для совместной работы РезюмеОберегайте ваши типы от непреднамеренного поиска, зависящего от аргументов (argument-dependent lookup — ADL, известный также как поиск Кёнига); однако преднамеренный
79. Храните в контейнерах только значения или интеллектуальные указатели
79. Храните в контейнерах только значения или интеллектуальные указатели РезюмеХраните к контейнерах объекты-значения. Контейнеры полагают, что их содержимое имеет тип значения, включая непосредственно хранящиеся значения, интеллектуальные указатели и
2.4. Предотвращение конфликта имен с помощью пространств имен
2.4. Предотвращение конфликта имен с помощью пространств имен ПроблемаВ несвязанных между собой модулях обнаружены конфликтующие имена или требуется заранее избежать возможности таких конфликтов, создав логические группы кода.РешениеДля структурирования кода
Типы, характеризуемые значениями, ссылочные типы и оператор присваивания
Типы, характеризуемые значениями, ссылочные типы и оператор присваивания Теперь изучите следующий метод Main() и рассмотрите его вывод, показанный на рис. 3.12.static void Main(string[] args) { Console.WriteLine("*** Типы, характеризуемые значением / Ссылочные типы ***"); Console.WriteLine(-› Создание p1"); MyPoint
Типы, характеризуемые значениями и содержащие ссылочные типы
Типы, характеризуемые значениями и содержащие ссылочные типы Теперь, когда вы чувствуете разницу между типами, характеризуемыми значением, и ссылочными типами, давайте рассмотрим более сложный пример. Предположим, что имеется следующий ссылочный тип (класс),
Типы, характеризуемые значениями, и ссылочные типы: заключительные замечания
Типы, характеризуемые значениями, и ссылочные типы: заключительные замечания Чтобы завершить обсуждение данной темы, изучите информацию табл. 3.8, в которой приводится краткая сводка основных отличий между типами, характеризуемыми значением, и ссылочными типами.Таблица
Ubuntu — абсолютно свободный дистрибутив
Ubuntu — абсолютно свободный дистрибутив Дистрибутив Ubuntu является абсолютно свободным. Вы его можете свободно распространять и даже модифицировать и распространять под своим именем. Вам не нужно покупать отдельный диск для установки на каждый компьютер — с одного диска
Свободный софт в научной области
Свободный софт в научной области Автор: Шутов, ИльяГосударство, разбуженное делом Поносова, заинтересовалось тем, какой софт используется в учебных и научных учреждениях, что немедленно привело к спуску вниз приказов и инструкций «удалить нелицензионное ПО со всех
Софтерра: Свободный космос
Софтерра: Свободный космос Автор: Илья ШпаньковКогда вы последний раз смотрели на звезды? Нет, не мельком бросив взгляд на ночное небо, а долго стояли запрокинув голову, наблюдая за таинственным мерцанием невообразимо далеких миров, медленно плывущих по бездонной
СОФТЕРРА: Программа-хамелеон: Свободный редактор с переднего края прогресса
СОФТЕРРА: Программа-хамелеон: Свободный редактор с переднего края прогресса Автор: Сергей ТокаревХамелеон умело маскируется под окружающую среду, растворяясь на фоне ветвей и листвы [Вообще-то, хамелеоны меняют свой цвет скорее в зависимости от состояния, а не для
Кафедра Ваннаха: Национально-свободный софт Ваннах Михаил
Кафедра Ваннаха: Национально-свободный софт Ваннах Михаил Опубликовано 14 апреля 2011 года Интересы и деяния государства нашего поразительно разнообразны. Ну вот известно, что любят в Стране Родимых Осин инновации. Да так, что в 2005 году аж учредили
Ориентация в пространстве
Ориентация в пространстве Итак, поиски связки ключей и забытые фамилии вы можете спокойно отнести к разряду нормальных явлений: никаких причин для беспокойства, и в первую очередь никаких оснований предполагать начинающуюся деменцию. Но как обстоит дело с умением