Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Полиморфизм. Перегрузка операций и функций
Одним из базовых принципов объектно-ориентированного стиля програм-мирования является полиморфизм. Это свойство, которое позволяет одно и то же имя использовать для решения двух или более назначений. Целью полиморфизма, применительно к ООП, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных. Одни и те же знаки операций (из списка уже существующих) могут быть определены и для объектов, введенных пользователем. Например, описав класс «вектор в трехмерном пространстве», не нужно придумывать имя функции для выполнения операции сложения над векторами, а можно переопределить смысл имеющийся операции «+» таким образом, что сложение двух векторов будет записываться в привычной форме: А + В. Транслятор также может различать функции не только по именам, но и по типам аргументов, поэтому вполне допустимым является наличие, например, двух следующих функций: int sqr (int x) {return (x*x)} float sqr (float x) {return (x*x)} Код какой конкретно функции будет использован при вызове зависит от типа фактического аргумента. Перегруженные функции хорошо использовать при введении новых данных. Описав тип COMPLEX для работы с комплексными числами, можно составить функцию pow() для возведения в степень комплексного числа, а назвать ее так же, как и функцию, работающую с вещественными числами. Формат перегрузки операторов: [< класс> ] operator < оператор> (< параметры>) { < выражения>; return(< выражения>); } Пример. Переопределим некоторые операции (" +", " -", " ^", " %", " *") для нахождения суммы, разности, скалярного произведения, векторного произведения двух заданных векторов, а также произведение каждого из них на скаляр. #define g goto #define o odin #define d dva #define t tri #include < stdlib.h> #include < string.h> #include < stdio.h> #include < conio.h> struct St //структура вектор {int s[4]; }; St operator + (St a, St b) //перегрузка операции + {static St sum; int i; for (i=1; i< =3; i++) {sum.s[i] = a.s[i]+b.s[i]; } return sum; } St operator - (St a, St b) //перегрузка операции – {static St sum; int i; for (i=1; i< =3; i++){sum.s[i]=a.s[i]-b.s[i]; } return sum; } int operator ^ (St a, St b) //перегрузка операции ^ {int i, sum = 0; for (i=1; i< =3; i++) {sum += a.s[i] * b.s[i]; } return sum; } St operator % (St a, St b) //перегрузка операции % {static St sum; int i; sum.s[1] = a.s[2] * b.s[3] - a.s[3] * b.s[2]; sum.s[2] = -(a.s[1] * b.s[3] - a.s[3] * b.s[1]); sum.s[3] = a.s[1] * b.s[2] - a.s[2] * b.s[1]; return sum; } St operator * (St a, int b) //перегрузка операции * {static St sum; int i; for (i=1; i< =3; i++){sum.s[i]=a.s[i]*b; } return sum; } void main() //основная программа { static St a, b, c; int j, res, con; char vibor; clrscr(); randomize(); printf(" ВВЕДИТЕ КООРДИНАТЫ ВЕКТОРА a "); scanf(" %d %d %d", & a.s[1], & a.s[2], & a.s[3]); printf(" ВВЕДИТЕ КООРДИНАТЫ ВЕКТОРА b "); scanf(" %d %d %d", & b.s[1], & b.s[2], & b.s[3]); ddd: printf(" a=(%d, %d, %d)\n", a.s[1], a.s[2], a.s[3]); printf(" b=(%d, %d, %d)\n", b.s[1], b.s[2], b.s[3]); printf(" ОПЕРАЦИЯ"); printf(" => 1: a+b; 2: a-b; 3: (a, b); 4: [axb]; 5: const*a; 6: const*b; 0: EXIT\n"); vibor=getch(); switch (vibor) { case '1': {c=a+b; g o; } case '2': {c=a-b; g o; } case '3': {res=a^b; g d; } case '4': {c=a%b; g o; } case '5': { printf(" ВВЕДИТЕ сonst "); scanf(" %d", & con); c=a*con; g o; } case '6': { printf(" ВВЕДИТЕ сonst "); scanf(" %d", & con); c = b*con; g o; } case '0': {g t; } } odin: printf(" результат с = (%d, %d, %d) \n", c.s[1], c.s[2], c.s[3]); g ddd; dva: printf(" результат %d\n", res); g ddd; tri: } Аргументы по умолчанию При объявлении функции в языке С++ для нее можно задать аргументы по умолчанию. Например, объявление void fun(int, int=5); позволяет вызвать функцию fun двумя способами, например fun(10) и fun(10, 20). Когда у функции задан только один аргумент, второй аргумент получит значение, заданное по умолчанию. Поэтому вызов fun(10) назначит первому аргументу значение 10, а второму – 5. Второй вызов fun(10, 20) назначит аргументам значения 10 и 20. Пример: #include < iostream.h> void fun(int, char='%', float=1.25); // Объявление функции void fun(int=1, char, float); // Переобъявление функции void fun(char *); // Объявление функции void main() { int ii=10; char cc='*'; float ff=22.33; fun(ii); // Результат 10 % 1.25 fun(ii, cc); // Результат 10 * 1.25 fun(ii, cc, ff); // Результат 10 * 22.33 fun(" HELLO\n"); // Результат HELLO fun(); // Результат 1 % 1.25 } void fun (int i, char c, float f) // Описание функции {cout < < i < < '\t' < < c < < '\t' < < f < < '\t' < < endl; } void fun (char *s) {cout< < s; }
Второе объявление void fun(int=1, char, float); добавляет в первую функцию значение первого аргумента, заданного по умолчанию. Для обоих объявлений достаточно одного описания. Новую функцию fun, заданную в виде void fun(char *), можно отличить по числу аргументов, поэтому неоднозначности не возникает. Если функция имеет аргумент, заданный по умолчанию, то после него могут идти только аргументы, тоже заданные по умолчанию. Например: int f1(int a, char b = '#', float f); // Не верно int f2(int a, char b = '#', float f = 5.28); // Нет ошибки Рассмотрим пример 2: #include < iostream.h>
|