d19ac7cd70bfb0afd5948d5a35cbfe4c.ppt
- Количество слайдов: 29
Полиморфизм Прикладное программирование кафедра прикладной и компьютерной оптики
2 Полиморфизм – возможность принимать множество форм, иметь разный смысл в зависимости от ситуации Полиморфизм в языке С++ позволяет программисту: n n создавать функции, имеющие одинаковые имена, но разные наборы аргументов (перегрузка функций) определять действие операторов для новых АТД (перегрузка операторов)
3 Перегрузка функций – использование одного имени для функций, выполняющих действия с аргументами разных типов void print(double d); void print(Lens l); void print(double x, double y); Если бы не было перегрузки функций print_int(int i); print_char(char c); print_Lens(Lens l);
4 Поиск подходящей перегруженной функции Последовательность поиска n n проверка точного соответствия типов попытка “повышения типов” (short -> int, float -> double. . . ) попытка стандартных преобразований (int -> double, double -> int, . . . ) преобразование явно задаваемое программистом Автоматическое преобразование типов n n bool, char повышается до int < long < float < double Явное преобразование типов n n (тип) выражение тип (выражение) Возвращаемые типы не участвуют в определении какую из перегруженных функций вызвать. float sqrt(float); float sqrt(double); double sqrt(double);
5 Преобразование типов при помощи конструктора // преобразование из double в Complex: : Complex(double x) { m_re=x; m_im=0. ; } // пример использования Complex x; x=Complex(3. 14); // оператор explicit запрещает неявный вызов конструктора для преобразования типа class Matrix { public: explicit Matrix(int size); } Matrix: : Matrix(int size) { m_data=new double[size*size]; }
6 Аргументы функции по умолчанию n описание полного конструктора с параметрами по умолчанию Lens(double r 1, double r 2, double D=0. , double d=0. , double n=1. ); n реализация полного конструктора с параметрами по умолчанию Lens: : Lens(double r 1, double r 2, double D, double d, double n) : m_r 1(r 1) , m_r 2(r 2) , m_d(d) , m_D(D) , m_n(n) { } n аргументы по умолчанию должны быть указаны в конце списка аргументов и подряд Lens Lens lens(100. , -100. ); // r 1=100 r 2=-100 D=0 d=0 lens(100. , -100. , 50. ); // r 1=100 r 2=-100 D=50 d=0 lens(100. , -100. , 50. , 10. ); // r 1=100 r 2=-100 D=50 d=10 lens(100. , -100. , 50. , 1. 5); // r 1=100 r 2=-100 D=0 d=10 lens(100. , -100. , 1. 5); // r 1=100 r 2=-100 D=1. 5 d=0 n=1 n=1. 5 n=1
7 Перегрузка операторов Для абстрактного типа данных Complex: n n n * – комплексное умножение + – комплексное сложение ~ – комплексное сопряжение Complex x, y, z; z=x*y; z=x. operator*(y); // явный вызов оператора class Complex { … Complex operator*(const Complex& other) const; … }
8 Перегрузка бинарных операторов // оператор умножения Complex: : operator*(const Complex& other) const { return Complex(m_re*other. m_re-m_im*other. m_im, m_re*other. m_im-m_im*other. m_re); } // смешанная арифметика Complex: : operator*(const double& other) const { return Complex(m_re*other, m_im*other); } // пример использования Complex x, z; double y; z=x*y;
9 Перегрузка унарных операторов // унарный минус Complex: : operator-() const { return Complex(-m_re, -m_im); } // сопряжение Complex: : operator~() const { return Complex(m_re, -m_im); } // пример использования Complex x, y; y=-x; y=~x;
10 Перегрузка логических операторов // оператор равенства bool Complex: : operator== (const Complex& other) const { return (m_re == other. m_re && m_im == other. m_im); } // пример использования Complex x, y; if(x==y) { … }
11 Перегрузка оператора присваивания Правила перегрузки оператора присваивания n n аргументом должна быть неизменяемая ссылка на экземпляр данного класса перед присваиванием необходимо сделать проверку на присваивание самому себе присваивание должно быть поэлементное оператор должен возвращать ссылку на самого себя // оператор присваивания Complex& Complex: : operator=(const Complex& other) { if(this != &other) { m_re=other. m_re; m_im=other. m_im; } return *this; } // пример использования Complex x, y, z; x=y=z=1;
12 Перегрузка операторов с присваиванием Правила перегрузки с присваиванием n n аргументом должна быть неизменяемая ссылка на экземпляр данного класса оператор должен возвращать ссылку на самого себя // умножение с присваиванием Complex& Complex: : operator*=(const Complex& other) { Complex temp(*this); m_re=temp. m_re*other. m_re - temp. m_im*other. m_im; m_im=temp. m_re*other. m_im + temp. m_im*other. m_re; return *this; } // пример использования Complex x, y; x*=y;
13 Перегрузка преобразования типов // преобразование типа Complex в double Complex: : operator double() const { return (m_re*m_re-m_im*m_im); } // пример использования Complex x; double y; y=double(x);
14 Перегрузка индексирования // индексирование double& matrix: : operator() (int i, int j) { return (p[i][j]); // или p[i*size+j]; } // пример использования matrix x; double y; y=matrix(1, 1); // доступ к элементу (1, 1)
15 Перегрузка операторов ввода/вывода Оформляются как дружественные функции класса // описание friend ostream& operator<< (ostream& out, const Complex& x); friend istream& operator>> (istream& out, Complex& x); // объявление ostream& operator<< (ostream& out, const Complex& x) { return (out<<”(“<
16 Неперегружаемые операторы Оператор : : левый и правый операнд являются не значениями, а именем Оператор. правый операнд является именем Оператор. * правый операнд является именем Оператор ? : арифметический оператор имеет специфическую семантику Оператор new операнд является именем, кроме того выполняет небезопасную процедуру Оператор delete не используется без new, кроме того выполняет небезопасную процедуру Нельзя определить новые операторы См. пример программы
17 Параметрический полиморфизм позволяет многократно использовать один и тот же код применительно к разным типам n тип указывается как параметр функции или класса Шаблоны (templates) – средство для реализаций параметризированных классов и функций на языке С++
18 Шаблоны функций void swap(int& x, int& y) { int temp; temp=x; x=y; y=temp; } template
19 Шаблоны функций с несколькими параметрами // пример 1 template
20 Пример шаблона класса template
21 Пример шаблона класса //////////////////////// // оператор сопряжения template
22 Инстанцирование шаблона – процесс генерации объявления класса по шаблону и аргументу Complex
23 Объекты-функции – объекты, у которых перегружен оператор вызова функций operator() Объекты-функции в
24 Стандартный объект-функция negate vector
25 Создание объекта-функции Rand template
26 Преобразование бинарной функции в унарную n Унарная функция – участвует один элемент (отрицание) Бинарная функция – участвуют два элемента (сложение, умножение, . . . ) n Умножение каждого элемента на 2 – как? n transform(v. begin(), v. end(), v. begin(), multiplies
27 Предикаты позволяют без изменения шаблона изменять критерии сравнения элементов контейнера и другие подобные действия. n объект-функция возвращает значение bool Объекты-функции в
28 Стандартный объект-функция greater void main() { vector
29 Создание предиката In. Range // параметры – тип данных и возвращаемое значение оператора () class In. Range : public unary_function