Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
39
Добавлен:
16.04.2013
Размер:
62.98 Кб
Скачать

Перегрузка и выбор функций

Перегруженные функции являются важным дополнением C++. Конкретная функция выбирается в зависимости от соответствия списка аргументов при вызове функции списку параметров в объявлении функции. Когда вызывается перегруженная функ­ция, компилятор должен иметь алгоритм для выбора надлежащей функции. Алго­ритм, который выполняет этот выбор, зависит от того, преобразования какого типа присутствуют. Наилучшее соответствие должно быть уникальным. Оно должно быть лучшим по крайней мере для одного аргумента и так же хорошо, как остальные соответствия, для всех других аргументов.

Ниже приведен алгоритм соответствия для каждого аргумента.

Алгоритм выбора перегруженной функции

1. Использовать строгое соответствие (если возможно).

2. Попробовать стандартное повышение типа (см. раздел 2.5 на стр. 46).

3. Попробовать стандартное преобразование типа.

4. Попробовать определяемое пользователем преобразование.

5. Использовать, если возможно, соответствие эллипсису (подразумеваемому ар­гументу).

Стандартное повышение типа (promotion) лучше, чем остальные стандартные преоб­разования. Повышение — это преобразования float в double, а также bool, char, short или enum в int. Кроме того, к стандартным преобразованиям относятся пре­образования указателей.

Несомненно, строгое соответствие является наилучшим. Для достижения такого соответствия могут использоваться приведения (cast). Компилятор не справится с двусмысленной ситуацией. Поэтому не следует полагаться на тонкие различия в ти­пах и неявные преобразования, которые делают перегруженную функцию неясной. Если вы сомневаетесь, используйте явные преобразования для обеспечения строгого соответствия.

Напишем перегруженную функцию greater () (больше) и будем следовать на­шему алгоритму для разных вызовов. В этом примере имеется пользовательский тип rational (рациональный).

В файле rational.срр

//Перегруженные функции

class rational{

public:

rational (int n=0) : a(n), q(1) {}

rational (int i, int j) : a(i), q(j) {}

rational (double r) : q(BIG), a(r * BIG) {}

void print () const {cout << a << “/” << q;}

operator double() {return static_cast<double> (a)/q;}

private:

long a, q;

enum {BIG = 100};

};

inline int greater(int i, int j)

{ return ( i > j ? i : j); }

inline double greater(double x, double y)

{ return ( x > у ? x : y); }

inline rational greater(rational w, rational z)

{ return (w > z ? w : z); }

int main()

{

int i = 10, j = 5;

float x = 7.0;

double y = 14.5;

rational w(10), z(3.5), zmax;

cout << “\ngreater(“ << i << “, “ << j << “) = ”

<< greater(i, j) ;

cout << “\ngreater(“ << x << “, “ << y << “) = “

<< greater(x, y) ;

cout << “\ngreater(“ << i << “, “ ;

z.print() ;

cout << “) = “ << greater(static_cast<rational>(i), z) ;

zmax = greater(w, z) ;

cout << “\ngreater(“;

w.print () ;

cout << “ , “;

z.print() ;

cout << “) = “ ;

zmax.print();

}

Вот что выведет эта программа:

greater(10, 5) = 10

greater(7, 14.5) = 14.5

greater(10, 350 / 100) = 10

greater(10 / 1, 350 / 100) =10/1

Применялись различные правила преобразования — и явные, и неявные.

Соседние файлы в папке Тельминов (мб)