Выбор перегруженной функции

Перегрузка операторов

Перегрузка функций

Перегруженные функции – это функции с одним и тем же именем, но имеющие разные списки параметров. Параметры могут отличаться типами и/или количеством. Тип возвращаемого функцией значения во внимание не принимается.

Примеры:

void f(int);

void f(char);

void f(long);

void f(float, int);

void f(int, int, int);

Функции с параметрами, заданными по умолчанию - пример перегрузки функций. Важно! перегружаемые функции не должны иметь совпадающие списки параметров (в том числе и при использовании параметров по умолчанию).

Вместе с приведенными выше примерами не может быть задана функция

void f(long, float = 0, char = '*');

но можно задать такую функцию:

void f(float, long = 0, char = '*');

Правила перегрузки операторов: только унарные и бинарные, почти все операторы; составное имя функции – operator знак_операции. Приоритет оператора, правило ассоциативности и количество операндов изменить нельзя!

Пример перегрузки бинарного оператора (сложение для класса Rational):

class Rational{

public:

...

Rational operator +(Rational r);

...

}

Rational Rational::operator +(Rational r)

{

Rational tmp;

tmp.num = num*r.den + den*r.num;

tmp.den = den*r.den;

tmp.reduce();

return tmp;

}

Унарные операторы перегружаются аналогично, за исключением ++ и — (они могут иметь префиксную и постфиксную формы записи):

Префиксная ++:

Rational operator ++();

Постфиксная ++:

Rational operator ++(int);

Использование перегруженных операторов:

Rational a(1,5), b(2,7), c;

c = a + b; // классическая запись: c = a.operator +(b);

a++; // классическая запись: a.operator ++(int);

++a; // классическая запись: a.operator ++();

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

Правила сравнения:

1. Точные совпадения

2. Расширения

3. Стандартные преобразования

4. Преобразования, требующие временные переменные

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

Преобразования, требующие временные переменные: параметр объявлен как ссылка, а аргумент требует преобразования (например, преобразование из float в int&) или задан выражением, значение которого не может быть изменено.