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


Устоявшие функции и последовательности пользовательских преобразований


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

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

Конвертеры наследуются, как и любые другие функции-члены класса. Например, мы можем написать следующий конвертер для ZooAnimal:

class ZooAnimal {

public:

   // конвертер: ZooAnimal ==> const char*

   operator const char*();

   // ...

};

Производный класс Bear наследует его от своего базового ZooAnimal. Если значение типа Bear используется в контексте, где ожидается const char*, то неявно вызывается конвертер для преобразования Bear в const char*:

extern void display( const char* );

Bear yogi;

// правильно: yogi ==> const char*



display( yogi );

Конструкторы с одним аргументом без ключевого слова explicit образуют другое множество неявных преобразований: из типа параметра в тип своего класса. Определим такой конструктор для ZooAnimal:

class ZooAnimal {

public:

   // преобразование: int ==> ZooAnimal

   ZooAnimal( int );

   // ...

};

Его можно использовать для приведения значения типа int к типу ZooAnimal. Однако конструкторы не наследуются. Конструктор ZooAnimal нельзя применять для преобразования объекта в случае, когда целевым является тип производного класса:

const int cageNumber = 8788l

void mumble( const Bear & );

// ошибка: ZooAnimal( int ) не используется

mumble( cageNumber );

Поскольку целевым типом является Bear – тип параметра функции mumble(), то рассматриваются только его конструкторы.



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