SlideShare a Scribd company logo
1 of 29
Прикладное программирование
кафедра
прикладной и компьютерной оптики
Полиморфизм
2
Полиморфизм
Полиморфизм – возможность принимать множество
форм, иметь разный смысл в зависимости от ситуации
Полиморфизм в языке С++ позволяет программисту:
 создавать функции, имеющие одинаковые имена, но разные наборы
аргументов (перегрузка функций)
 определять действие операторов для новых АТД (перегрузка операторов)
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
Поиск подходящей перегруженной
функции
Последовательность поиска
 проверка точного соответствия типов
 попытка “повышения типов” (short -> int, float -> double ...)
 попытка стандартных преобразований (int -> double, double -> int, ...)
 преобразование явно задаваемое программистом
Автоматическое преобразование типов
 bool, char повышается до int
 int < long < float < double
Явное преобразование типов
 (тип) выражение
 тип (выражение)
Возвращаемые типы не участвуют в определении какую из
перегруженных функций вызвать.
float sqrt(float);
float sqrt(double);
double sqrt(double);
5
Преобразование типов при
помощи конструктора
// преобразование из double в Complex
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
Аргументы функции по умолчанию
 описание полного конструктора с параметрами по умолчанию
Lens(double r1, double r2, double D=0., double d=0., double n=1.);
 реализация полного конструктора с параметрами по умолчанию
Lens::Lens(double r1, double r2, double D, double d, double n)
: m_r1(r1) , m_r2(r2) , m_d(d) , m_D(D) , m_n(n)
{ }
 аргументы по умолчанию должны быть указаны в конце списка аргументов и
подряд
Lens lens(100.,-100.); // r1=100 r2=-100 D=0 d=0 n=1
Lens lens(100.,-100.,50.); // r1=100 r2=-100 D=50 d=0 n=1
Lens lens(100.,-100.,50.,10.); // r1=100 r2=-100 D=50 d=10 n=1
Lens lens(100.,-100.,50.,10.,1.5);// r1=100 r2=-100 D=0 d=10 n=1.5
Lens lens(100.,-100.,1.5); // r1=100 r2=-100 D=1.5 d=0 n=1
7
Перегрузка операторов
Для абстрактного типа данных Complex:
 * – комплексное умножение
 + – комплексное сложение
 ~ – комплексное сопряжение
Complex x,y,z;
z=x*y;
z=x.operator*(y); // явный вызов оператора
class Complex
{
…
Complex operator*(const Complex& other) const;
…
}
8
Перегрузка бинарных операторов
// оператор умножения
Complex 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 Complex::operator*(const double& other) const
{
return Complex(m_re*other, m_im*other);
}
// пример использования
Complex x, z;
double y;
z=x*y;
9
Перегрузка унарных операторов
// унарный минус
Complex Complex::operator-() const
{
return Complex(-m_re, -m_im);
}
// сопряжение
Complex 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
Перегрузка оператора
присваивания
Правила перегрузки оператора присваивания
 аргументом должна быть неизменяемая ссылка на экземпляр данного класса
 перед присваиванием необходимо сделать проверку на присваивание самому себе
 присваивание должно быть поэлементное
 оператор должен возвращать ссылку на самого себя
// оператор присваивания
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
Перегрузка операторов с
присваиванием
Правила перегрузки с присваиванием
 аргументом должна быть неизменяемая ссылка на экземпляр данного
класса
 оператор должен возвращать ссылку на самого себя
// умножение с присваиванием
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<<”(“<<x.m_re<<”,”<<x.m_im<<”)”);
}
// пример использования
Complex x;
cout<<x<<endl;
16
Неперегружаемые операторы
Оператор ::
левый и правый операнд являются не значениями, а именем
Оператор .
правый операнд является именем
Оператор .*
правый операнд является именем
Оператор ? :
арифметический оператор имеет специфическую семантику
Оператор new
операнд является именем, кроме того выполняет небезопасную процедуру
Оператор delete
не используется без new, кроме того выполняет небезопасную процедуру
Нельзя определить новые операторы См. пример программы
17
Параметрический полиморфизм
Параметрический полиморфизм позволяет многократно
использовать один и тот же код применительно к разным
типам
 тип указывается как параметр функции или класса
Шаблоны (templates) – средство для реализаций
параметризированных классов и функций на языке С++
18
Шаблоны функций
void swap(int& x, int& y)
{
int temp;
temp=x;
x=y;
y=temp;
}
// использование шаблона
double x=1, y=5;
swap<double> (x, y); // TYPE заменяется на double
 Инстанцирование – генерация функции по шаблону и ее аргументу
template<class TYPE>
void swap(TYPE& x, TYPE& y)
{
TYPE temp;
temp=x;
x=y;
y=temp;
}
См. пример программы
19
Шаблоны функций с несколькими
параметрами
// пример 1
template<class PAR1, class PAR2>
bool transform(PAR1 x, PAR2& y)
{
if(sizeof(y) < sizeof(x))
{
return false;
}
y=(PAR2)x;
return true;
}
// пример 2
template<class PAR, int n>
PAR factorial()
{
PAR sum=1;
i=1;
while(i<=n)
{
sum*=i;
i++;
}
return sum;
}
20
Пример шаблона класса
template <class PAR>
class Complex
{
protected:
PAR m_re, m_im; //вещественная и мнимая часть
public:
Complex(); // конструктор по умолчанию
Complex(PAR re, PAR im=PAR(0)); // полный конструктор
Complex(const Complex<PAR>& other); // конструктор копирования
// получение параметров комплексного числа
PAR GetRe() const;
PAR GetIm() const;
// перегруженные операторы
Complex<PAR> operator*(const Complex<PAR>& other) const;
Complex<PAR>& operator=(const Complex<PAR>& other);
Complex<PAR> operator~() const;
};
21
Пример шаблона класса
///////////////////////////////////////////////
// оператор сопряжения
template <class PAR>
Complex<PAR> Complex<PAR>::operator~() const
{
return Complex<PAR>(m_re, -m_im);
}
///////////////////////////////////////////////
template <class PAR>
ostream& operator<< (ostream& out, const Complex<PAR>& other);
///////////////////////////////////////////////
// вывод на экран
template <class PAR>
ostream& operator<< (ostream& out, const Complex<PAR>& other)
{
return (out<<”(“<<other.GetRe()<<”,”<<other.GetIm()<<”)”);
}
///////////////////////////////////////////////
22
Инстанцирование шаблона
Инстанцирование шаблона – процесс генерации
объявления класса по шаблону и аргументу
Complex<int> a(5), b(3,3);
Complex<double> x(1.144, -0.155);
См. пример программы
23
Объекты-функции
Объекты-функции – объекты, у которых перегружен
оператор вызова функций operator()
Объекты-функции в <functional> :
 plus – сложение
 minus – вычитание
 multiplies – умножение
 divides – деление
 modulus – деление по модулю
 negate – отрицание
24
Стандартный объект-функция
negate
vector<int> v;
vector<int>::iterator it=v.begin();
while(it != v.end())
{
*it = -(*it);
it++;
}
// то же самое с использование объекта-функции negate
transform(v.begin(),v.end(), v.begin(), negate<int>());
// вывод на экран
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
// чтение из стандартного потока
copy(istream_iterator<int>(cin), istream_iterator<int>(),
back_inserter(v));
25
Создание объекта-функции Rand
template <class PAR>
// параметры – тип данных и возвращаемое значение оператора ()
class Rand : public unary_function<PAR, void>
{
PAR m_min, m_max;
public:
Rand(PAR min, PAR max)
: m_min(min), m_max(max)
{ }
void operator() (PAR& i)
{
i=(PAR)(rand()*(m_max-m_min))/RAND_MAX+m_min;
}
};
// использование объекта-функции Rand
for_each(v.begin(), v.end(), Rand<int>(-10,10));
26
Преобразование бинарной
функции в унарную
 Унарная функция – участвует один элемент (отрицание)
 Бинарная функция – участвуют два элемента (сложение, умножение, ...)
 Умножение каждого элемента на 2 – как?
transform(v.begin(), v.end(), v.begin(), multiplies<int>());
 Функция binder2nd – преобразует бинарную функцию в унарную, и принимает второй
аргумент как параметр бинарной функции (<functional>)
// умножение каждого элемента на 2
transform (v.begin(), v.end(), v.begin(),
bind2nd(multiplies<int>(), 2));
См. пример программы
27
Предикаты
Предикаты позволяют без изменения шаблона изменять
критерии сравнения элементов контейнера и другие
подобные действия.
 объект-функция возвращает значение bool
Объекты-функции в <functional>
 equal_to бинарный предикат равенства
 not_equal_to бинарный предикат неравенства
 greater бинарный предикат >
 less бинарный предикат < (используется по умолчанию)
 greater_equal бинарный предикат >=
 less_equal бинарный предикат <=
 logical_and бинарный предикат И
 logical_or бинарный предикат ИЛИ
 logical_not унарный предикат НЕ
28
Стандартный объект-функция
greater
void main()
{
vector<int> v(10);
for_each(v.begin(), v.end(), Rand<int>(-5,5));
// sort(v.begin(), v.end());
// reverse(v.begin(), v.end());
// сортировка в порядке убывания
sort(v.begin(), v.end(), greater<int>());
}
29
Создание предиката InRange
// параметры – тип данных и возвращаемое значение оператора ()
class InRange : public unary_function<int, bool>
{
int m_left, m_right;
public:
InRange(int left, int right)
: m_left(left), m_right(right)
{}
bool operator() (const int& i)
{
return (i>m_left && i<m_right);
}
};
// использование InRange
vector<int> v(10);
for_each(v.begin(), v.end(), Rand<int>(0,10000));
cout << count_if(v.begin(), v.end(), InRange(1000,10000));
См. пример программы

More Related Content

What's hot

Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Dima Dzuba
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыPlatonov Sergey
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о BoostSergey Platonov
 
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Roman Orlov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыcorehard_by
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
javascript_part1
javascript_part1javascript_part1
javascript_part1sovest
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузераPlatonov Sergey
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.Igor Shkulipa
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклыSergey Nemchinsky
 

What's hot (18)

Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
 
лек3 4
лек3 4лек3 4
лек3 4
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10Объектно-ориентированное программирование. Лекции 9 и 10
Объектно-ориентированное программирование. Лекции 9 и 10
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
javascript_part1
javascript_part1javascript_part1
javascript_part1
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.C++ Базовый. Занятие 02.
C++ Базовый. Занятие 02.
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклы
 

Similar to Lecture 5

5.1 Перегрузка операторов
5.1 Перегрузка операторов5.1 Перегрузка операторов
5.1 Перегрузка операторовDEVTYPE
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxYandex
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
javascript
javascriptjavascript
javascriptsovest
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptSmartTools
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.Igor Shkulipa
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...OdessaFrontend
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.Infinity
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++mcroitor
 
Функциональное программирование и Clojure
Функциональное программирование и ClojureФункциональное программирование и Clojure
Функциональное программирование и ClojureAnjLab
 
ZFConf 2010: Zend Framework and Doctrine
ZFConf 2010: Zend Framework and DoctrineZFConf 2010: Zend Framework and Doctrine
ZFConf 2010: Zend Framework and DoctrineZFConf Conference
 
Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Sergey Schetinin
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиSQALab
 

Similar to Lecture 5 (20)

лекция 2
лекция 2лекция 2
лекция 2
 
5.1 Перегрузка операторов
5.1 Перегрузка операторов5.1 Перегрузка операторов
5.1 Перегрузка операторов
 
Михаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajaxМихаил Давыдов - Транспорт, ajax
Михаил Давыдов - Транспорт, ajax
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
javascript
javascriptjavascript
javascript
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
 
лекция 2
лекция 2лекция 2
лекция 2
 
Step cpp022
Step cpp022Step cpp022
Step cpp022
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
Функциональное программирование и Clojure
Функциональное программирование и ClojureФункциональное программирование и Clojure
Функциональное программирование и Clojure
 
ZFConf 2010: Zend Framework and Doctrine
ZFConf 2010: Zend Framework and DoctrineZFConf 2010: Zend Framework and Doctrine
ZFConf 2010: Zend Framework and Doctrine
 
Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование Декораторы в Python и их практическое использование
Декораторы в Python и их практическое использование
 
Тестирование программных фильтров безопасности
Тестирование программных фильтров безопасностиТестирование программных фильтров безопасности
Тестирование программных фильтров безопасности
 

More from Anastasia Snegina

птп по ппп 2013 2014
птп по ппп 2013 2014 птп по ппп 2013 2014
птп по ппп 2013 2014 Anastasia Snegina
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14Anastasia Snegina
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошинаAnastasia Snegina
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошинаAnastasia Snegina
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике вAnastasia Snegina
 
рп по пр практике в
рп по пр практике врп по пр практике в
рп по пр практике вAnastasia Snegina
 
рп по у сп практике в
рп по у сп практике врп по у сп практике в
рп по у сп практике вAnastasia Snegina
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике втAnastasia Snegina
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике втAnastasia Snegina
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике втAnastasia Snegina
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике втAnastasia Snegina
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике втAnastasia Snegina
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике втAnastasia Snegina
 

More from Anastasia Snegina (20)

птп по ппп 2013 2014
птп по ппп 2013 2014 птп по ппп 2013 2014
птп по ппп 2013 2014
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14
 
я.прогр птп
я.прогр птпя.прогр птп
я.прогр птп
 
пп кос вт
пп кос втпп кос вт
пп кос вт
 
пп кос в
пп кос впп кос в
пп кос в
 
пп кос в
пп кос впп кос в
пп кос в
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошина
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошина
 
пп кос вт
пп кос втпп кос вт
пп кос вт
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике в
 
рп по пр практике в
рп по пр практике врп по пр практике в
рп по пр практике в
 
рп по у сп практике в
рп по у сп практике врп по у сп практике в
рп по у сп практике в
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике вт
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике вт
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике вт
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике вт
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике вт
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике вт
 
лр18
лр18лр18
лр18
 
лр15
лр15лр15
лр15
 

Lecture 5

  • 1. Прикладное программирование кафедра прикладной и компьютерной оптики Полиморфизм
  • 2. 2 Полиморфизм Полиморфизм – возможность принимать множество форм, иметь разный смысл в зависимости от ситуации Полиморфизм в языке С++ позволяет программисту:  создавать функции, имеющие одинаковые имена, но разные наборы аргументов (перегрузка функций)  определять действие операторов для новых АТД (перегрузка операторов)
  • 3. 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. 4 Поиск подходящей перегруженной функции Последовательность поиска  проверка точного соответствия типов  попытка “повышения типов” (short -> int, float -> double ...)  попытка стандартных преобразований (int -> double, double -> int, ...)  преобразование явно задаваемое программистом Автоматическое преобразование типов  bool, char повышается до int  int < long < float < double Явное преобразование типов  (тип) выражение  тип (выражение) Возвращаемые типы не участвуют в определении какую из перегруженных функций вызвать. float sqrt(float); float sqrt(double); double sqrt(double);
  • 5. 5 Преобразование типов при помощи конструктора // преобразование из double в Complex 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. 6 Аргументы функции по умолчанию  описание полного конструктора с параметрами по умолчанию Lens(double r1, double r2, double D=0., double d=0., double n=1.);  реализация полного конструктора с параметрами по умолчанию Lens::Lens(double r1, double r2, double D, double d, double n) : m_r1(r1) , m_r2(r2) , m_d(d) , m_D(D) , m_n(n) { }  аргументы по умолчанию должны быть указаны в конце списка аргументов и подряд Lens lens(100.,-100.); // r1=100 r2=-100 D=0 d=0 n=1 Lens lens(100.,-100.,50.); // r1=100 r2=-100 D=50 d=0 n=1 Lens lens(100.,-100.,50.,10.); // r1=100 r2=-100 D=50 d=10 n=1 Lens lens(100.,-100.,50.,10.,1.5);// r1=100 r2=-100 D=0 d=10 n=1.5 Lens lens(100.,-100.,1.5); // r1=100 r2=-100 D=1.5 d=0 n=1
  • 7. 7 Перегрузка операторов Для абстрактного типа данных Complex:  * – комплексное умножение  + – комплексное сложение  ~ – комплексное сопряжение Complex x,y,z; z=x*y; z=x.operator*(y); // явный вызов оператора class Complex { … Complex operator*(const Complex& other) const; … }
  • 8. 8 Перегрузка бинарных операторов // оператор умножения Complex 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 Complex::operator*(const double& other) const { return Complex(m_re*other, m_im*other); } // пример использования Complex x, z; double y; z=x*y;
  • 9. 9 Перегрузка унарных операторов // унарный минус Complex Complex::operator-() const { return Complex(-m_re, -m_im); } // сопряжение Complex Complex::operator~() const { return Complex(m_re, -m_im); } // пример использования Complex x, y; y=-x; y=~x;
  • 10. 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. 11 Перегрузка оператора присваивания Правила перегрузки оператора присваивания  аргументом должна быть неизменяемая ссылка на экземпляр данного класса  перед присваиванием необходимо сделать проверку на присваивание самому себе  присваивание должно быть поэлементное  оператор должен возвращать ссылку на самого себя // оператор присваивания 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. 12 Перегрузка операторов с присваиванием Правила перегрузки с присваиванием  аргументом должна быть неизменяемая ссылка на экземпляр данного класса  оператор должен возвращать ссылку на самого себя // умножение с присваиванием 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. 13 Перегрузка преобразования типов // преобразование типа Complex в double Complex::operator double() const { return (m_re*m_re-m_im*m_im); } // пример использования Complex x; double y; y=double(x);
  • 14. 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. 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<<”(“<<x.m_re<<”,”<<x.m_im<<”)”); } // пример использования Complex x; cout<<x<<endl;
  • 16. 16 Неперегружаемые операторы Оператор :: левый и правый операнд являются не значениями, а именем Оператор . правый операнд является именем Оператор .* правый операнд является именем Оператор ? : арифметический оператор имеет специфическую семантику Оператор new операнд является именем, кроме того выполняет небезопасную процедуру Оператор delete не используется без new, кроме того выполняет небезопасную процедуру Нельзя определить новые операторы См. пример программы
  • 17. 17 Параметрический полиморфизм Параметрический полиморфизм позволяет многократно использовать один и тот же код применительно к разным типам  тип указывается как параметр функции или класса Шаблоны (templates) – средство для реализаций параметризированных классов и функций на языке С++
  • 18. 18 Шаблоны функций void swap(int& x, int& y) { int temp; temp=x; x=y; y=temp; } // использование шаблона double x=1, y=5; swap<double> (x, y); // TYPE заменяется на double  Инстанцирование – генерация функции по шаблону и ее аргументу template<class TYPE> void swap(TYPE& x, TYPE& y) { TYPE temp; temp=x; x=y; y=temp; } См. пример программы
  • 19. 19 Шаблоны функций с несколькими параметрами // пример 1 template<class PAR1, class PAR2> bool transform(PAR1 x, PAR2& y) { if(sizeof(y) < sizeof(x)) { return false; } y=(PAR2)x; return true; } // пример 2 template<class PAR, int n> PAR factorial() { PAR sum=1; i=1; while(i<=n) { sum*=i; i++; } return sum; }
  • 20. 20 Пример шаблона класса template <class PAR> class Complex { protected: PAR m_re, m_im; //вещественная и мнимая часть public: Complex(); // конструктор по умолчанию Complex(PAR re, PAR im=PAR(0)); // полный конструктор Complex(const Complex<PAR>& other); // конструктор копирования // получение параметров комплексного числа PAR GetRe() const; PAR GetIm() const; // перегруженные операторы Complex<PAR> operator*(const Complex<PAR>& other) const; Complex<PAR>& operator=(const Complex<PAR>& other); Complex<PAR> operator~() const; };
  • 21. 21 Пример шаблона класса /////////////////////////////////////////////// // оператор сопряжения template <class PAR> Complex<PAR> Complex<PAR>::operator~() const { return Complex<PAR>(m_re, -m_im); } /////////////////////////////////////////////// template <class PAR> ostream& operator<< (ostream& out, const Complex<PAR>& other); /////////////////////////////////////////////// // вывод на экран template <class PAR> ostream& operator<< (ostream& out, const Complex<PAR>& other) { return (out<<”(“<<other.GetRe()<<”,”<<other.GetIm()<<”)”); } ///////////////////////////////////////////////
  • 22. 22 Инстанцирование шаблона Инстанцирование шаблона – процесс генерации объявления класса по шаблону и аргументу Complex<int> a(5), b(3,3); Complex<double> x(1.144, -0.155); См. пример программы
  • 23. 23 Объекты-функции Объекты-функции – объекты, у которых перегружен оператор вызова функций operator() Объекты-функции в <functional> :  plus – сложение  minus – вычитание  multiplies – умножение  divides – деление  modulus – деление по модулю  negate – отрицание
  • 24. 24 Стандартный объект-функция negate vector<int> v; vector<int>::iterator it=v.begin(); while(it != v.end()) { *it = -(*it); it++; } // то же самое с использование объекта-функции negate transform(v.begin(),v.end(), v.begin(), negate<int>()); // вывод на экран copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); // чтение из стандартного потока copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));
  • 25. 25 Создание объекта-функции Rand template <class PAR> // параметры – тип данных и возвращаемое значение оператора () class Rand : public unary_function<PAR, void> { PAR m_min, m_max; public: Rand(PAR min, PAR max) : m_min(min), m_max(max) { } void operator() (PAR& i) { i=(PAR)(rand()*(m_max-m_min))/RAND_MAX+m_min; } }; // использование объекта-функции Rand for_each(v.begin(), v.end(), Rand<int>(-10,10));
  • 26. 26 Преобразование бинарной функции в унарную  Унарная функция – участвует один элемент (отрицание)  Бинарная функция – участвуют два элемента (сложение, умножение, ...)  Умножение каждого элемента на 2 – как? transform(v.begin(), v.end(), v.begin(), multiplies<int>());  Функция binder2nd – преобразует бинарную функцию в унарную, и принимает второй аргумент как параметр бинарной функции (<functional>) // умножение каждого элемента на 2 transform (v.begin(), v.end(), v.begin(), bind2nd(multiplies<int>(), 2)); См. пример программы
  • 27. 27 Предикаты Предикаты позволяют без изменения шаблона изменять критерии сравнения элементов контейнера и другие подобные действия.  объект-функция возвращает значение bool Объекты-функции в <functional>  equal_to бинарный предикат равенства  not_equal_to бинарный предикат неравенства  greater бинарный предикат >  less бинарный предикат < (используется по умолчанию)  greater_equal бинарный предикат >=  less_equal бинарный предикат <=  logical_and бинарный предикат И  logical_or бинарный предикат ИЛИ  logical_not унарный предикат НЕ
  • 28. 28 Стандартный объект-функция greater void main() { vector<int> v(10); for_each(v.begin(), v.end(), Rand<int>(-5,5)); // sort(v.begin(), v.end()); // reverse(v.begin(), v.end()); // сортировка в порядке убывания sort(v.begin(), v.end(), greater<int>()); }
  • 29. 29 Создание предиката InRange // параметры – тип данных и возвращаемое значение оператора () class InRange : public unary_function<int, bool> { int m_left, m_right; public: InRange(int left, int right) : m_left(left), m_right(right) {} bool operator() (const int& i) { return (i>m_left && i<m_right); } }; // использование InRange vector<int> v(10); for_each(v.begin(), v.end(), Rand<int>(0,10000)); cout << count_if(v.begin(), v.end(), InRange(1000,10000)); См. пример программы