|
Программирование >> Аргументация конструирования
/ / выражение №2 i = i t с ; Первое выражение складывает int с double. В C++ не определена функция op-erator+(int, double), но определена функция operator+(double, double). При отсутствии функции (int, double) C++ конвертирует int i в double (говорят, что i приведено к double ), чтобы использовать версию (double, double). Для обоих выражений выполняется один и тот же процесс, однако со вторым выражением ситуация еще хуже, поскольку результат типа double должен быть урезан до типа переменной i, т.е. int. Приведение объектов пользовательских типов Если программист определяет метод приведения из встроенного типа к пользовательскому классу, C++ попытается использовать его для того, чтобы выражение приобрело смысл. вы создали конструктор для конвертирования double В JSDollar. class USDollar friend USDollar Operator+(USDollari si, USDollari s2); public; USDollar(int d, in c) ; USDollar(double value) { dollars = (int)value; cents = (Int) ((value - dol lars) * 1 (i 0 + 0.5) ; . тоже, чт ьше ... С помощью этого фрагмента кода вы предоставили C++ путь приведения double в USDollar. (Теперь, когда C++ почувствует себя стесненным в наличных средствах, он сможет заложить немного double.) Эту особенность преобразования можно перенести в наши операции: void fn (USDollarS s) все приведенные выражения operatort (USDollarS, USDollars) s + s; явное s= 1.5 + s; .. .неявное преобразование. . , s=s+1.5; ...в обратном порядке... s = s даже здесь используется преобразование int в double, а затем все идет по старому сценарию Теперь вам не нужно определять ни operator+ (double, USDollars), ни opera- tor+(USDollari, double). С++ преобразует double в USDollar и использует уже определенную функцию operatorf (USDollars, USDollars) . Это преобразование может быть указано в явном виде, как это сделано в первом сложении. Однако это же преобразование будет выполнено автоматически, если даже не было указано явно. Реализация такого преобразования помогает сберечь много усилий за счет уменьшения количества разных операторов, которые в противном случае должен определить программист. Распространенная ошибка № 5. Довольно опасно доверят++ автоматическое проведение таких преобразований. Если компилятор не сможет определить, какой тип преобразования нужно использовать, он просто выдаст сообщение об ошибке. Оператор явного преобразования Оператор преобразования также может быть перегружен. На практике это выглядит так: class USDollar public: USDollar{double value = 0.0); operator double!) return dollars + cents/100.0; protected: unsigned int dollars; unsigned int cents; USDollar::USDollar(double value) dollars = (int)value cents = (int)((value - dollars) * 100 + 0.5); Оператор преобразования operator double () представляет собой метод преобразования из USDollar в double, в результате которого будет создано действительное значение, равное количеству долларов плюс количество центов, деленное на 100. На практике операторы такого рода используются следующим образом: in (int argcs, char* pArgs [ ] ) { USDollar dl{2.0), d2(1.5), d3; явн ьзуем оператор преобразования d3 = USDollar((double)dl + (double)d2); или неявно d3 = dl + d2; return 0; Оператор преобразования состоит из слова operator и следующего за ним названия типа, в который необходимо преобразовать объект. Функция-член usDoliar: :operator double О обеспечивает механизм преобразования класса USDollar в double. По причинам, которые от меня не зависят, операторы преобразования не имеют типа возвращаемого значения. (Создатели C++ аргументировали это так: Вам не нужен тип возвращаемого значения, поскольку его можно узнать из имени . К сожалению, создатели C + + не очень последовательны.) В первом выражении мы преобразуем две переменные USDollar в double, используем для сложения существующую функцию operator+ (double, double), а затем преобразуем результат обратно в USDollar с помощью конструктора. Второе выражение приводит к тому же эффекту, но более хитрым путем. C + + пытается разобраться с выражением d3 = dl + d2, сначала конвертируя dl и d2 в double, а затем конвертируя сумму обратно в USDollar. Логика этого процесса такая-%, как и в первом выражении, однако в данном случае работу, где это только возможно, берет на себя C++. Этот пример демонстрирует как преимущества, так и недостатки оператора преобразования. Обеспечивая C + + функцией преобразования из USDollar в double, программист освобождается от необходимости создавать полный набор операторов. Класс USDollar может просто воспользоваться операторами, определенными ДЛЯ double. С другой стороны, предоставление метода преобразования лишает программиста возможности контролировать, какие из операторов определены. Если определена функция преобразования в double, для USDollar будут использоваться операторы double независимо от того, имеет ли это смысл. Кроме того, выполнение большого количества преобразований приведет к значительному уменьшению эффективности программы. Например, приведенное только что простое сложение требует выполнения трех функций преобразования и всех сопутствующих им функций умножения, деления и т.п. Правила для неявных преобразований Разбираясь со всеми этими преобразованиями, я так и не объяснил, как C + + поступит со сложением USDollar dl и double d2. Правила для таких операций достаточно просты. 1 Сначала C + + ишет функцию operator+ (USDollar, double). 2. Если она не найдена, C + + ищет функцию, которая может быть использована для преобразования USDollar в double. 3. И паконец, С + + ищет функцию, которая преобразует хоть что-то из этих двух переменных в нечто иное. Первый пункт ясен, поскольку соответствующая функция уникальна; однако два последних пункта несколько туманны. Распросграненная ошибка № 6. Если возможен более чем один способ выполнения операции, на этапе компиляции будет сгенерирована ошибка. Если существует два возможных преобразования объекта, компилятор также выдаст ошибку. Распросграненная ошибка № 7. Вы не можете предоставить два способа выполнения преобразования для одного типа. Например, приведенный ниже код вызовет сообщение об ошибке. class A public: А(В& Ъ) ; class В public: operator A{);
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |