АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Перегрузка функций (методов класса). Почему следует использовать перегрузку. Перегрузка функций, перегрузка конструкторов

Читайте также:
  1. Автоматизация функций в социальной работе
  2. Алекс и Дженнифер удивлённо смотрели друг на друга. Он думал, почему она так встречает его, а девочка - что он делает здесь.
  3. АНАЛИЗ ФУНКЦИЙ СПЕЦИАЛИСТОВ ПО СТРАТЕГИЧЕСКОМУ МЕНЕДЖМЕНТУ И ПОЛНОМОЧИЙ ОРГАНОВ УПРАВЛЕНИЯ ОРГАНИЗАЦИИ, ПРИНИМАЮЩИХ СТРАТЕГИЧЕСКИЕ РЕШЕНИЯ.
  4. Анализ функций управления
  5. Б) Вычисление тригонометрических функций.
  6. Билет9(почему Россия разгромила наполеона а крымскую войну проиграла)
  7. В какие инстанции следует обращаться в случае нарушения прав и свобод, гарантированных Европейским Союзом?
  8. В какой срок расследуется специальное расследование?
  9. В каком случае испытуемые должны были лучше запоминать числа и почему?
  10. В отделении находится запас белья на сутки. Запрещается сушить белье на радиаторах центрального отопления и использовать его повторно.
  11. В случае если родятся сын и дочь, то как следует разделить наследство?
  12. В этот момент все искажения пропали, появилась картинка лагеря демонов, но почему-то вверх ногами. Под нашими вопросительными взглядами Сергей занервничал.

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

Функция starline() выводит на экран линию из 45 символов *, а функция repchar() выводит заданный символ заданное число раз, используя два аргумента. charline() всегда печатает 45 символов, но позволяет задавать печатаемый символ. Все три функции, starline(), repchar() и charline(), выполняют схожие действия, но их имена различны. Для программиста это означает, что нужно запомнить эти имена и различия между действиями функций. Очевидно, что было бы гораздо удобнее использовать одно и то же имя для всех трех функций, несмотря на то, что они используют различные наборы аргументов.

#include <iostream>

using namespace std;

void repchar(); // прототипы

void repchar(char); void repchar(char, int);

int main() {

repchar(); repchar('='); repchar('+', 30); return 0;

}

//---функция repchar()-----------------------------

// выводит на экран 45 символов '*'

void repchar() {

for(int j=0; j<45; j++) // цикл, выполняющийся 45 раз cout << '*'; // вывод символа '*'

cout << endl;

}

//--- функция repchar()----------------------------- // выводит 45 заданных символов

void repchar(char ch) {

for(int j=0; j<45; j++) // цикл, выполняющийся 45 раз cout << ch; // вывод заданного символа

cout << endl;

}

Первые две из линий имеют длину 45 символов, третья — 30 символов.

В программе содержатся три функции с одинаковым именем. Каждой из функций соответствует свое объявление, определение и вызов. Каким же образом компилятор различает между собой эти три функции? Здесь на помощь приходит сигнатура функции, которая позволяет различать между собой функции по количеству аргументов и их типам. Другими словами, объявление void repchar(); не содержащее аргументов, и объявление void repchar(char, int); задают разные функции.

// функция repchar() выводит заданный символ заданное число раз

void repchar(char ch, int n) {

for(int j=0;j<n; j ++) // цикл, выполняющийся n раз cout << ch; // вывод заданного символа

cout << endl;

}

Эта программа выводит на экран три различных вида линий: *********************************************

=================================

++++++++++++++++++++++++++++++

Различные типы аргументов

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

#include <iostream>

using namespace std;

struct Distance

{

int feet; float inches;

};

void engldisp(Distance); // прототипы

void engldisp(float);

int main() {

Distance d1; // длина типа Distance

float d2; // длина типа float

// ввод значения d1

cout << "\nВведите число футов: "; cin >> d1.feet; cout << "Введите число дюймов: "; cin >> d1.inches; // ввод значения d2

cout << "Введите длину в дюймах: "; cin >> d2; cout << "\nd1 = ";

engldisp(d1); // вывод значения d1

cout << "\nd2 = ";

engldisp(d2); // вывод значения d2

cout << endl; return 0;

}

//-------- функция engldisp()----------------

void engldisp(Distance dd) // параметр dd типа Distance {

cout <<dd.feet <<"\'-" << dd.inches <<"\""; }

//--------------------------------------------------------

//engldisp()

// вывод переменной типа float в футах и дюймах

void engldisp(float dd) // параметр dd типа float {

int feet =static_cast<int>(dd /12); float inches = dd - feet*12;

cout <<feet <<"\'-" << inches <<"\""; }

Пользователю предлагается ввести два расстояния: первое — в виде отдельно вводимых количества футов и количества дюймов, а второе — в виде количества дюймов (например, 109,5 дюймов вместо 9'-1,5"). Программа вызывает перегруженную функцию engldisp() для того, чтобы вывести первое значение, имеющее тип Distance(), и второе значение, имеющее тип float.

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

Использование перегруженных функций упрощает процесс разработки программы, так как у программиста нет необходимости запоминать множество имен функций.

Перегруженные конструкторы

Было бы удобно производить инициализацию переменных класса Distance в момент их создания, то есть использовать объявления типа Distance width(5, 6.25); где определяется объект width, сразу же инициализируемый значениями 5 и 6.25 для футов и дюймов соответственно. Чтобы сделать это, вызовем конструктор следующим образом:

Distance(int ft, float in): feet(ft), inches(in) { }

Мы инициализируем поля feet и inches теми значениями, которые передаются конструктору в качестве аргументов.

Тем не менее, мы хотим сохранить возможность определять переменные класса Distance без инициализации, подобно тому, как мы делали в программе.

В программе ENGLOBJ не было конструктора, но определения работали без ошибок. Это связано с наличием конструктора без параметров, называемого конструктором по умолчанию.

Если же для нас важно, какими значениями будут инициализироваться поля объекта класса, то нам следует явно определить конструктор.

Distance(): feet(O), inches(O.O) //конструктор по умолчанию

{ } //тело функции пусто, никаких действий не производится

Члены класса инициализируются константными значениями, в данном сл чае целым значением 0 для переменной feet и вещественным значением 0.0 для переменной inches. Значит, мы можем использовать объекты, инициализируемые с помощью конструктора без параметров, будучи уверенными в том, что поля объекта имеют нулевые, а не другие, случайные, значения.

Теперь у нас имеется два явно определенных конструктора с одним и тем же именем Distance(), и поэтому говорят, что конструктор является перегруженным. Какой из этих двух конструкторов исполняется во время создания нового объекта, зависит от того, сколько аргументов используется при вызове:

Distance length; //вызывает первый конструктор

Distance width(11, 6.0); //вызывает второй конструктор

 


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.)