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