Функции не могут отличаться только типами возвращаемого значения. Если списки параметров функций совпадают, а типы возвращаемого значения отличаются, то это будет ошибкой:

Record lookup(const Account&);

bool lookup(const Account&); // ошибка: отличается только типом

                             // возвращаемого значения

Различие типов параметров

Два списка параметров могут быть идентичными, даже если они не выглядят одинаково:

// каждая пара объявляет ту же функцию

Record lookup(const Account &acct);

Record lookup(const Account&); // имена параметров игнорируются

typedef Phone Telno;

Record lookup(const Phone&);

Record lookup(const Telno&);   // Telno и Phone того же типа

Первое объявление в первой паре именует свой параметр. Имена параметров предназначены только для документирования. Они не изменяют список параметров.

Во второй паре типы только выглядят разными, Telno — не новый тип, это только синоним типа Phone. Псевдоним типа (см. раздел 2.5.1) предоставляет альтернативное имя для уже существующего типа, а не создает новый тип. Поэтому два параметра, отличающиеся только тем, что один использует имя типа, а другой его псевдоним, не являются разными.

Перегрузка и константные параметры

Как упоминалось в разделе 6.2.3, спецификатор const верхнего уровня (см. раздел 2.4.3) никак не влияет на объекты, которые могут быть переданы функции. Параметр, у которого есть спецификатор const верхнего уровня, неотличим от такового без спецификатора const верхнего уровня:

Record lookup(Phone);

Record lookup(const Phone);  // повторно объявляет Record lookup(Phone)

Record lookup(Phone*);

Record lookup(Phone* const); // повторно объявляет

                             // Record lookup(Phone*)

Здесь вторые объявления повторно объявляет ту же функцию, что и первые. С другой стороны, функцию можно перегрузить на основании того, является ли параметр ссылкой (или указателем) на константную или неконстантную версию того же типа; речь идет о спецификаторе const нижнего уровня:

// функции, получающие константную и неконстантную ссылку (или

// указатель), имеют разные параметры

Record lookup(Account&);       // функция получает ссылку на Account

Record lookup(const Account&); // новая функция получает константную

                               // ссылку

Record lookup(Account*);       // новая функция получает указатель

                               // на Account

Record lookup(const Account*); // новая функция получает указатель на

                               // константу

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

Перейти на страницу:

Похожие книги