|
Программирование >> Расширенная версия языка c++
5.5. Перегрузка и неоднозначность При перегрузке возможно внесение неоднозначности в программу. Неоднозначность (ambiguity), вызванная перегрузкой функций, может быть введена в программу при преобразовании типа, а также при использовании парамет-ров-сс1лок и аргументов по умолчанию. Некоторые виды неоднозначности вызываются самой перегрузкой функций. Другие виды связаны со способом вызова перегруженных функций. Чтобы программа компилировалась без ошибок, от неоднозначности необходимо избавиться. Примеры J, 1. Один из наиболее частых видов неоднозначности вызывается правилами преобразования типа в C++. Как вы знаете, при вызове функции с аргументом, тип которого совместим (но не аналогичен) с типом параметра, которому он передается, тип аргумента по умолчанию преобразуется в тип параметра. Об этой операции иногда говорят как о приведении типа (type promotion). Приведение типа - это такой вид преобразования типа, который позволяет некоторым функциям, например putchar(), вызываться с символьным параметром, даже тогда, когда аргумент функции имеет тип int. Однако в некоторых случаях это преобразование типа при перегрузке функций вызовет ситуацию неоднозначности. Чтобы понять, как это происходит, исследуем следующую программу: Эта программа даржит ошибку неоднозначности #include <iostream> using namespace std; float L (float i} . return i / 2 - 0; ВИЯМИ. Если в вашем компиляторе применяются такие функции, создайте функцию myclreolO, которая стирает строку, начиная от текущей позиции курсора до конца строки. Передайте этой функции параметр, задающий число стираем1х позиций. Если параметр не задавать, то по умолчанию должна стираться вся строка. В противном случае должно стираться число символьных позиций, заданное параметром. 4. Что неправильно в следующем прототипе функции с аргументом по умолчанию? int f(int count, int max = count); double oublG i) . - return i /3.0; ,. I ..... . ./ int main () float x = 10.09; ; y- : : ->-*.i: > - double у = 10.09; cou f(x); нет неоднозначности используется функция f (float) cou f (y) ; / / нет неоднозначности используется функция f (double) cou f(10); неоднозначность j куда преобразовать 10? j * в значение типа double или float? return 0; Как указано в комментариях к функции main(), компилятор в состоянии выбрать правильную версию функции f(), если она вызывается либо с переменными типа double, либо с переменными типа float. Однако что случается, если она вызывается с целым? Какую функцию вызовет компилятор Г<Поа1) или f(donble)? (Оба преобразования правильны!) И в том, и в другом случае правильно привести тип int либо к типу float, либо к типу double. Таким образом, возникает ситуация неоднозначности. Этот пример выявляет также то, как неоднозначность може мляться при вызове перегруженных функций. Очевидно, что сама по себе неоднозначность не присуща перегруженным версиям функции f(), пока каждая вызывается с аргументом соответствующего типа. 2. Другой пример перегрузки функции, которая сама по себе не должна приводить к неоднозначности. Тем не менее, при вызове с аргументом неправильного типа, правила преобразования типа C++ создают ситуацию неоднозначности. Эта программа неоднозначна #include <iostreaitt> using namespace std; ч voi igned char c) cout c; void f (char c) cout << c; - . . return 0 ; Когда функция f() вызывается с числовой константой 86, компилятор не может понять, какую версию функции вызвать: f(un$igBed char) или f(char). Оба преобразования одинаково правильны, что и ведет к неоднозначности. 3. Один из видов неоднозначности ьияется, если вы пытаетесь перегрузить функции, единственным отличием которых является то, что одна использует параметр-ссылку, а другая параметр-значение по умолчанию. В рамках формального синтаксиса C++ у компилятора нет способа узнать, какую функцию вызвать. Запомните, что нет синтаксических отличий между вызовом функции по значению и вызовом функции по ссылке. Например: Эта программа неоднозначна ttinclude <iostream> using namespace Std; int f{int a, int b) { return a + b; . . . , здесь внутренняя неоднозначность int a, int return a - b; , - - . , J : int mainO int X = 1, у = 2; г i- cou << f(x y) ; какую версии f (j вызвать? return 0; Здесь вызов функции у) неоднозначен, поскольку вызвана может быть любая версия функции. При этом компилятор выставит флаг ошибки даже раньше того, как встретится такая инструкция, поскольку сама перегрузка этих двух функций внутренне неоднозначна, и компилятор не будет знать, какую из них предпочесть. 4. Другим видом неоднозначности при перегрузке функций является случай, когда одна или более перегруженных функций используют аргумент по умолчанию. Рассмотрим программу: . . int main () . . , f(c); f{a6); какая версия функции f() вызывается?
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |