double arrow

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

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

  1. Использовать точное соответствие, если оно найдено
  2. Проверить поддержку стандартных типов
  3. Проверить стандартные преобразования типов
  4. Проверить преобразования, определяемые пользователем
  5. Использовать соответствие для аргументов, если оно найдено

Рассмотрим пример.
class complex

{

double real,imag;

public:

complex(double r) { real=r; imag=0; }

void assign(double r,double i) { real=r; imag=i; }

void print() { cout << real << “+”<<imag<<”i”; }

// обеспечивает преобразование complex в double

operator double() { return sqrt(real*real+imag*imag); }

};

inline int greater(int i,int j) { return (i > j)? i:j; }

inline double greater(double i,double j) { return (i > j)? i:j; }

inline complex greater(complex i,complex j) { return (i > j)? i:j; }

void main() {

int i=5,j=10;

float x=7;

double y=14;

complex w(0),z(0);

w.assign(x,y); // требует преобразования float x в double

z.assign(i,j); // оба параметра преобразуются в double

// выбирает первое определение greater по правилу соответствия

cout << greater(i,j) << endl;

// Выбирает второе определение greater, так как использовано стандартное расширяющее преобразование из float в double

cout << greater(x,y) << endl;

// Второе определение greater выбирается из-за точного соответствия //правилу.

cout << greater(y,double(z)) << endl;

// точно соответствует третьему определению

cout << greater(w,z) << endl;

}

Функция-член преобразования operator double требуется для оценки условия w<z. Complex переменные w z преобразуются в double. Для возвращаемого типа не необходимости в преобразовании.
Для избежания неоднозначности необходимо явное преобразование double(z). Если вместо этого будет использоваться вызов функции:
greater(y,z); // error
то он будет иметь два доступных преобразования, достигших соответствия. Преобразования параметра y из double в complex, определяемое пользователем, соответствует третьему определению. Преобразование z из complex в double, также определяемое пользователем, соответствует второму определению. Но второе определение функции имеет лучшее соответствие для первого параметра, между тем как третья функция имеет лучшее соответствие для второго параметра. Это нарушает требование о том, чтобы “Максимальное соответствие должно быть уникально. Оно должно быть лучше всего для, по крайне мере, одного параметра и одинаково хорошо для всех остальных”.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



Сейчас читают про: