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



         

Функции-кандидаты - часть 2


namespace NS {

   class ZooAnimal {

      friend void display( const ZooAnimal& );

   };

}

// базовый класс Bear объявлен в пространстве имен NS

class Bear : public NS::ZooAnimal { };

int main() {

   Bear baloo;

   display( baloo );

   return 0;

}

Аргумент baloo функции display() имеет тип Bear. В его базовом классе ZooAnimal функция display() объявлена другом, поэтому она является членом пространства имен NS, хотя явно в нем не объявлена. При обычном просмотре NS она не была бы найдена. Однако поскольку аргумент display() имеет тип Bear, то объявленная в ZooAnimal функция-друг добавляется в множество кандидатов.

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

  • функций, видимых в точке вызова;
  • функций, объявленных в тех пространствах имен, где определен тип класса или любой из его базовых;
  • функций, являющихся друзьями этого класса или любого из его базовых.
  • Наследование влияет также на построение множества кандидатов для вызова функции-члена с помощью операторов “точка” или “стрелка”. В разделе 18.4 мы говорили, что объявление функции-члена в производном классе не перегружает, а скрывает одноименные функции-члены в базовом, даже если их списки параметров различны:

    class ZooAnimal {

    public:

       Time feeding_time( string );

       // ...

    };

    class Bear : public ZooAnimal {

    public:

       // скрывает ZooAnimal::feeding_time( string )

       Time feeding_time( int );

       // ...

    };

    Bear Winnie;

    // ошибка: ZooAnimal::feeding_time( string ) скрыта

    Winnie.feeding_time( "Winnie" );

    Функция-член feeding_time(int), объявленная в классе Bear, скрывает feeding_time(string), объявленную в ZooAnimal, базовом для Bear. Поскольку функция-член вызывается через объект Winnie типа Bear, то при поиске кандидатов для этого вызова просматривается только область видимости класса Bear, и единственным кандидатом будет feeding_time(int). Так как других кандидатов нет, вызов считается ошибочным.




    Содержание  Назад  Вперед