Обобщенное программироание Шаблоны

Содержание

Слайд 2

Понятие обобщенного программирования Обобщенным программированием называется создание универсального программного кода, инвариантного

Понятие обобщенного программирования

Обобщенным программированием называется создание универсального программного кода, инвариантного к

типу обрабатываемых данных.
Например:
функция выбора максимального или минимального из двух значений одинаково реализуются для разных числовых типов данных (int, float, double)
организация данных в виде стека или множества одинакова для элементов разных типов и т.д.
Английское название generic programming - “родовое программирование”
Непосредственно не связано с ООП, но замечательным образом сочетается
Языковые средства обобщенного программирования еще не «устоялись»
Слайд 3

Обобщенное программирование в С Макросы с параметрами - возможность простейшего обобщенного

Обобщенное программирование в С

Макросы с параметрами - возможность простейшего обобщенного программирования

функций
Пример: функция выбора максимального из двух значений #define max(x,y) ((x)>(y) ? (x) : (y))
Данный макрос пригоден для аргументов всех числовых типов (int, float, double)
Слайд 4

Функция сортировки массива qsort() Выполняет сортировку массива данных любого типа base

Функция сортировки массива qsort()

Выполняет сортировку массива данных любого типа
base - указатель

на сортируемый массив (или подмассив)
nelem - количество элементов, подлежащих сортировке (например, весь массив)
width - длина данных для элемента массива в байтах
fcmp - указатель на функцию сравнения элементов

void qsort(void* base, size_t nelem, size_t width, int(*fcmp)(const void*, const void*));

Слайд 5

Шаблоны классов. Параметризованные классы Контейнерные классы — классы, объединяющие атомарные объекты

Шаблоны классов. Параметризованные классы

Контейнерные классы — классы, объединяющие атомарные объекты -

элементы некоторого заданного типа. Примеры:
Список
Стек
Множество
и т.п
Слайд 6

Стек – описание класса class stack_char { public: stack_char(unsigned); ~stack_char(); void

Стек – описание класса

class stack_char {
public:
stack_char(unsigned);
~stack_char();
void push(char);

char pop();
unsiged size() const;
private:
char* base;
char* top;
unsigned max_size;
};

class stack_int {
public:
stack_int(unsiged);
~stack_int();
void push(int);
int pop();
unsigned size() const;
private:
int* base;
int* top;
unsigned max_size;
};

файл stack.h

Слайд 7

Стек – реализация методов #include “stack.h” #include #include stack_char::stack_char(unsigned sz) {

Стек – реализация методов

#include “stack.h”
#include
#include
stack_char::stack_char(unsigned sz) {
if ((top=base=new

char[max_size=sz])==NULL) {
cerr << “Нет свободной памяти для стека.\n”;
exit(1);
}
}
stack_char::~stack_char() {
delete [ ]base;
}

файл stack.cpp

Слайд 8

Стек – реализация методов (продолжение) void stack_char::push(char a) { if (size()

Стек – реализация методов (продолжение)
void stack_char::push(char a) {
if (size() == max_size)

cerr << “Переполнение стека.\n”;
*top++ = a;
}
char stack_char::pop(void) {
if (size() == 0) cerr << “Исчерпание стека.\n”;
return *--top;
}
unsigned stack_char::size(void) const {
return top-base;
}

файл stack.cpp

Слайд 9

Шаблон класса stack #ifndef __STACK_H #define __STACK_H template class stack {

Шаблон класса stack

#ifndef __STACK_H
#define __STACK_H
template class stack {
public:
stack(unsigned);
~stack();
void push(const

T&);
T pop(void);
unsigned size(void) const;
private:
T* base;
T* top;
unsigned max_size;
};
#endif

файл stack.h

Слайд 10

Шаблоны методов класса stack #ifndef __STACK_HPP #define __STACK_HPP #include “stack.h” #include

Шаблоны методов класса stack

#ifndef __STACK_HPP
#define __STACK_HPP
#include “stack.h”
#include
#include
template

stack::stack(unsigned sz) {
if ((top=base=new T[max_size=sz])==NULL) {
cerr << “Нет свободной памяти для стека.\n”;
exit(1);
}
}
template stack::~stack() {
delete [ ]base;
}

файл stack.hpp

Слайд 11

Шаблоны методов класса stack (продолжение) template void stack ::push(const T& a)

Шаблоны методов класса stack (продолжение)
template void stack::push(const T& a) {
if (size()

== max_size) cerr << “Переполнение стека.\n”;
*top++ = a;
}
template T stack::pop(void) {
if (size() == 0) cerr << “Исчерпание стека.\n”;
return *--top;
}
template unsigned stack::size(void) const {
return top-base;
}
#endif

файл stack.hpp

Слайд 12

Использование шаблона класса stack #include “point.h” #include “stack.h” #include “stack.hpp” void

Использование шаблона класса stack

#include “point.h”
#include “stack.h”
#include “stack.hpp”
void main(void)
{
stack sch(100);
stack sint(50);
stack sp(400);
sch.push(‘A’);
sint.push(111);
sp.push(Point(1,1));
........................
}

Слайд 13

Параметры шаблонов Шаблон может иметь несколько параметров Параметры шаблона не обязательно

Параметры шаблонов

Шаблон может иметь несколько параметров
Параметры шаблона не обязательно являются именами

типов
Кроме имен типов можно использовать константные выражения
Слайд 14

Параметры шаблонов template class stack { public: stack(); void push(const T&);

Параметры шаблонов
template class stack {
public:
stack();
void push(const T&);
T pop(void);
unsigned

size(void) const;
private:
T base[max_size];
T* top;
};

файл stack.cpp

Слайд 15

Параметры шаблонов #include template class stack ::stack() { top=base; } template

Параметры шаблонов

#include
template
class stack::stack() { top=base; }
template

T, unsigned max_size>
void stack::push(const T& a) {
if (size() == max_size) cerr << "Переполнение стека.\n";
*top++ = a;
}
template
T stack::pop(void) {
if (size() == 0) cerr << "Исчерпание стека.\n";
return *--top;
}
template
unsigned stack::size(void) const {
return top-base;
}
Слайд 16

Использование #include “point.h” void main(void) { stack sch; stack sint1; stack

Использование

#include “point.h”
void main(void) {
stack sch;
stack sint1;
stack sint2;
stack sp;
sch.push('A');
sint1.push(111);
sint2.push(111);
//

sint1 = sint2; - ошибка, т.к. переменные различных типов!
sp.push(Point(1,1));
}