С++ для начинающих


Как перегрузить имя функции


В C++ двум или более функциям может быть дано одно и то же имя при условии, что их списки параметров различаются либо числом параметров, либо их типами. В данном примере мы объявляем перегруженную функцию max():

int max ( int, int );

int max( const vector<int> & );

int max( const matrix & );

Для каждого перегруженного объявления требуется отдельное определение функции max() с соответствующим списком параметров.

Если в некоторой области видимости имя функции объявлено более одного раза, то второе (и последующие) объявление интерпретируется компилятором так:

  • если списки параметров двух функций отличаются числом или типами параметров, то функции считаются перегруженными:
  • // перегруженные функции

    void print( const string & );

    void print( vector<int> & );

    • если тип возвращаемого значения и списки параметров в объявлениях двух функций одинаковы, то второе объявление считается повторным:
    • // объявления одной и той же функции

      void print( const string &str );

      void print( const string & );



      Имена параметров при сравнении объявлений во внимание не принимаются;

      • если списки параметров двух функций одинаковы, но типы возвращаемых значений различны, то второе объявление считается неправильным (несогласованным с первым) и помечается компилятором как ошибка:
      • unsigned int max( int i1, int i2 );

        int max( int i1, int i2 ); // ошибка: отличаются только типы

                                   // возвращаемых значений

        Перегруженные функции не могут различаться лишь типами возвращаемого значения;

        • если списки параметров двух функций разнятся только подразумеваемыми по умолчанию значениями аргументов, то второе объявление считается повторным:
        • // объявления одной и той же функции

          int max ( int *ia, int sz );

          int max ( int *ia, int = 10 );

          Ключевое слово typedef создает альтернативное имя для существующего типа данных, новый тип при этом не создается. Поэтому если списки параметров двух функций различаются только тем, что в одном используется typedef, а в другом тип, для которого typedef служит псевдонимом, такие списки считаются одинаковыми, как, например, в следующих двух объявлениях функции calc(). В таком случае второе объявление даст ошибку компиляции, поскольку возвращаемое значение отличается от указанного раньше:


          // typedef не вводит нового типа

          typedef double DOLLAR;

          // ошибка: одинаковые списки параметров, но разные типы

          // возвращаемых значений

          extern DOLLAR calc( DOLLAR );

          extern int calc( double );

          Спецификаторы const или volatile при подобном сравнении не принимаются во внимание. Так, следующие два объявления считаются одинаковыми:

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

          void f( int );

          void f( const int );

          Спецификатор const важен только внутри определения функции: он показывает, что в теле функции запрещено изменять значение параметра. Однако аргумент, передаваемый по значению, можно использовать в теле функции как обычную инициированную переменную: вне функции изменения не видны. (Способы передачи аргументов, в частности передача по значению, обсуждаются в разделе 7.3.) Добавление спецификатора const к параметру, передаваемому по значению, не влияет на его интерпретацию. Функции, объявленной как f(int), может быть передано любое значение типа int, равно как и функции f(const int). Поскольку они обе принимают одно и то же множество значений аргумента, то приведенные объявления не считаются перегруженными. f() можно определить как

          void f( int i ) { }

          или как

          void f( const int i ) { }

          Наличие двух этих определений в одной программе – ошибка, так как одна и та же функция определяется дважды.

          Однако, если спецификатор const или volatile применяется к параметру указательного или ссылочного типа, то при сравнении объявлений он учитывается.

          // объявляются разные функции

          void f( int* );

          void f( const int* );

          // и здесь объявляются разные функции

          void f( int& );

          void f( const int& );


          Содержание раздела