Стандарты программирования на С++. 101 правило и рекомендация | страница 99
В этом разделе мы считаем наиболее значимой рекомендацию 58 — "Храните типы и функции в разных пространствах имен, если только они не предназначены для совместной работы".
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
, вызывающий код работать не будет. В этом случае имеется два способа заставить его заработать. Первый состоит в использовании явно квалифицированного оператора