Шаблоны в С++ презентация

Содержание

Шаблоны функций Многие алгоритмы не зависят от типов данных. #include using namespace std; void swap (int& a, int & b) { int t = a; a = b; b

Слайд 1Шаблоны в С++
Макаревич Л. Г.


Слайд 2Шаблоны функций
Многие алгоритмы не зависят от типов данных.
#include
using namespace

std;
void swap (int& a, int & b)
{
int t = a;
a = b;
b = t;
}
void swap (double& a, double & b)
{
double t = a;
a = b;
b = t;
}
void swap (char& a, char& b)
{
char t = a;
a = b;
b = t;
}

int main()
{
int i = 5, j = 6;
double d = 8.6789, b = 6.7894;
char c1='a', c2 = 'f';
swap (i, j);
swap (d, b);
swap (c1, c2);
}


Слайд 3template < class T>
void swap_templ (T& a, T & b)
{
T t

= a;
a = b;
b = t;
}
int main()
{
int i = 5, j = 6;
double d = 8.6789, b = 6.7894;
char c1='a', c2 = 'f';
swap_templ(i,j);
swap_templ(d,b);
swap_templ(c1,c2);
}

template < class A, class B, class C> void f( ) { …}

template < class T>
void f( T& a, int k)
{
a = a + k;
}
int main()
{
int i = 5;
f ( i, 99 ); //можно f(i,99);
//будет выполнено преобразование в //double
return 0;
}


Слайд 4template
const T& min(const T& a, const T& b)
{

if (a < b)
return a;
else
return b;
}

Данная запись еще не создала ни одной функции, это лишь шаблон для определенной функции. Только тогда, когда происходит обращение к функции с аргументами конкретного типа, будет выполнена генерация конкретной функции.

int x, y, z;
String s1, s2, s3;
. . .
// генерация функции min для класса String
s1 = min(s2, s3);
. . .
// генерация функции min для типа int
x = min(y, z); double d; x = min(y,d);// сообщение об ошибке

Первое обращение к функции min генерирует функцию

const String& min(const String& a,
const String& b);

Второе обращение генерирует функцию

const int& min(const int& a,
const int& b);

Слайд 5Explicit specification of the template arguments for a function template is

allowed. For example:
// function_templates2.cpp template void f(T) { } int myfunction(char j) { f(j); //generate the specialization f(int) }
When the template argument is explicitly specified, normal implicit conversions are done to convert the function argument to the type of the corresponding function template parameters. In the above example, the compiler will convert (char j) to type int.

Явное указание аргумента шаблона при вызове

template
void f(T k) {cout << k; }
int myfunction(char j)
{ f(j);
return 5;
}
int main()
{
myfunction ('a'); //97 печатается
return 0;
}


Слайд 6template < class T>
void f(int c , int k)
{

T& a;
a = a + k + c;
}
int main()
{
int i = 5;
f ( i, 99 ); // ошибка
return 0;
}

В списке параметров шаблона должны быть только классы, входящие в число входных аргументов функции
Тип возвращаемого значения может входить в список параметров шаблона, если такой тип есть во входных аргументах функции

template < class T>
T f(int c , int k)
{
T a = 0;
a = a + k + c;
return a;
}
int main()
{
int i = 5;
int k = f ( i, 99 );// ошибка
return 0;
}


Слайд 7#include
using namespace std;
template < class T >
void sort(T * a,

int n)// сортировка выбором
{
T t;
for ( int i = 0; i < n -1; i++ )
{
int imin = i;
for ( int j = i + 1; j < n; j++)
if ( a[j] < a[imin]) imin = j;
t = a[i]; a[i] = a[imin]; a[imin] = t;
}
}
int main()
{
const int n = 5;
int b[n];
for ( int i = 0; i< n; i++ ) cin >> b[i];
sort(b,n);
double d[] = {22, 5, 67, 4};
sort(d,4);
return 0;
}

Слайд 8Специализированные шаблоны
template < class T >
void sort(T * a, int n)
{

T t;
for ( int i = 0; i < n -1; i++ )
{
int imin = i;
for ( int j = i + 1; j < n; j++)
if ( a[j] < a[imin]) imin = j;
t = a[i]; a[i] = a[imin]; a[imin] = t;
}
}
void sort<>(int * a, int n)
{
cout << "Not sorted\n";
}
int main()
{
const int n = 5;
int b[n];
for ( int i = 0; i< n; i++ ) cin >> b[i];
sort(b,n);
double d[] = {22, 5, 67, 4};
sort(d,4);
return 0;
}

Слайд 9With a function template, you can define special behavior for a

specific type by providing a explicit specialization (override) of the function template for that type. Visual C++ 5.0 and later supports the new syntax for declaring explicit specializations of function templates. For example:
// explicit_specialization.cpp template void f(T t) { }; // Explicit specialization of f with 'char' with the // template argument explicitly specified: template<> void f(char c) { } // Explicit specialization of f with 'double' with the // template argument deduced: template<> void f(double d) { } int main() { }
The following form of old syntax is also supported:
// Explicit specialization of f with 'char' with the
// template argument deduced: // void f(char) {...}

Дополнительные возможности задания специализированных шаблонов


Слайд 10Шаблоны классов
Представьте контейнерный класс ( список, очередь, дерево, стек, …)
Контейнерный класс предназначен

для хранения данных

Слайд 11class List
{
class Elem
{
public:
int data;
Elem * next;
Elem *

prev;
Elem(){data = 0; next = prev = NULL;}
Elem( int d):data(d){next = prev = NULL;}
};
Elem * first;
Elem * last;
public:
List(void)
{
first = last = NULL;
}
~List(void)
{
Elem * pt = first;
while ( pt )
{
Elem * t = pt;
pt = pt->next;
delete t;
}
}

Elem * insert( int key, int d)// вставка после узла с ключом key
{
if (Elem * pkey = find(key))
{
Elem * pt = new Elem(d);
pt->next = pkey->next;
pt->prev = pkey;
pkey->next = pt;
if ( pkey != last ) (pt->next)->prev = pt;
else
last = pt;
return pt;
}
return 0;
}


Слайд 12 void Add( int d)// вставка в конец списка
{
Elem * t

= new Elem(d);
if ( first == NULL )
{
first = last = t;
}
else
{
t->prev = last;
last->next = t;
last = t;
}
}
void print()
{
Elem * pt = first;
while ( pt )
{
cout << pt->data << '\n';
pt = pt->next;
}

}

void print_reverse()
{
Elem * pt = last;
while ( pt )
{
cout << pt->data << '\n';
pt = pt->prev;
}

}
Elem * find ( int d )
{
Elem * pt = first;
while ( pt )
{
if ( pt->data == d ) return pt;
pt = pt->next;
}
return NULL;
}


Слайд 13bool remove( int key )
{
if (Elem * pkey = find(key))
{

if ( pkey == first )
{
first = first->next;
first->prev = NULL;
}
else
{
if ( pkey == last )
{
last = last ->prev;
last->next = NULL;
}
else
{
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
}
delete pkey; return true;
}
return false;
}
};

int main()
{
List l;
for ( int i = 1; i < 25; i++ ) l.Add(i);
l.print();
l.print_reverse();
l.insert(1,99);
if ( !l.remove(6)) cout << "Not founf!\n";
l.print();
l.print_reverse();
return 0;
}


Слайд 14template имя_класса { тело класса
}


Слайд 15template < class T> class List
{
class Elem
{
public:
T data;
Elem

* next;
Elem * prev;
Elem(){data = 0; next = prev = NULL;}
Elem( T d):data(d){next = prev = NULL;}
};
Elem * first;
Elem * last;
public:
List(void)
{
first = last = NULL;
}
~List(void)
{
Elem * pt = first;
while ( pt )
{
Elem * t = pt;
pt = pt->next;
delete t;
}
}

Elem * insert( T key, T d)// вставка после узла с ключом //key
{
if (Elem * pkey = find(key))
{
Elem * pt = new Elem(d);
pt->next = pkey->next;
pt->prev = pkey;
pkey->next = pt;
if ( pkey != last ) (pt->next)->prev = pt;
else
last = pt;
return pt;
}
return 0;
}


Слайд 16 void Add( T d)// вставка в конец списка
{
Elem * t

= new Elem(d);
if ( first == NULL )
{
first = last = t;
}
else
{
t->prev = last;
last->next = t;
last = t;
}
}
void print()
{
Elem * pt = first;
while ( pt )
{
cout << pt->data << '\n';
pt = pt->next;
}

}

void print_reverse()
{
Elem * pt = last;
while ( pt )
{
cout << pt->data << '\n';
pt = pt->prev;
}

}
Elem * find ( T d )
{
Elem * pt = first;
while ( pt )
{
if ( pt->data == d ) return pt;
pt = pt->next;
}
return NULL;
}


Слайд 17bool remove(T key )
{
if (Elem * pkey = find(key))
{
if

( pkey == first )
{
first = first->next;
first->prev = NULL;
}
else
{
if ( pkey == last )
{
last = last ->prev;
last->next = NULL;
}
else
{
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
}
delete pkey; return true;
}
return false;
}
};

int main()
{
List < int> l;
for ( int i = 1; i < 5; i++ ) l.Add(i);
l.print();
l.print_reverse();
l.insert(1,99);
if ( !l.remove(4)) cout << "Not found!\n";
l.print();
l.print_reverse();
List < char> lch;
for ( int i = 0; i < 5; i++ ) lch.Add('a'+i);
lch.print();
lch.print_reverse();
lch.insert('a','z');
if ( !lch.remove('a')) cout << "Not found!\n";
lch.print();
lch.print_reverse();

return 0;
}


Слайд 18Использование итераторов
#define NULL 0
#include
using namespace std;
template
class List
{
class Elem
{
public:
T

data;
Elem * next;
Elem * prev;
public:
Elem(){data = 0; next = prev = NULL;}
Elem( T d):data(d){next = prev = NULL;}
};

Elem * first;
Elem * last;
public:
List(void)
{
first = last = NULL;
}

~List(void)
{
Elem * pt = first;
while ( pt )
{
Elem * t = pt;
pt = pt->next;
delete t;
}
}

void Add( T d)// вставка в конец списка
{
Elem * t = new Elem(d);
if ( first == NULL )
{
first = last = t;
}
else
{
t->prev = last;
last->next = t;
last = t;
}
}
void print()
{
Elem * pt = first;
while ( pt )
{
cout << pt->data << '\n';
pt = pt->next;
}

}
public: class Iterator
{
List * p;
Elem * tek;

public:
Iterator(List *_p):p(_p){tek = p->first;}
T gettek(){return tek->data;}
bool next()
{
if ( tek == NULL ) return false;
tek = tek->next;
if ( tek != NULL) return true;
return false;
}
void setfirst(){ tek = p->first;}
};

};

void main()
{
List qq;
for ( int i = 0; i < 10; i++)
qq.Add(i);

List::Iterator it(&qq);

for ( i = 0; i < 5; i++)
{
cout << it.gettek()<< '\n';
it.next();
}
}


Слайд 19You can use class templates to create a family of classes

that operate on a type.
// class_templates.cpp template class TempClass { public: TempClass( void ); ~TempClass( void ); int MemberSet( T a, int b ); private: T Tarray[i]; int arraysize; }; int main() { TempClass < char, 88> ma; }
In this example, the templated class uses two parameters, a type T and an int i. The T parameter can be passed any type, including structures and classes. The i parameter has to be passed an integer constant. Because i is a constant defined at compile time, you can define a member array of size i using a standard array declaration.


Слайд 20Члены шаблонов
template class TempClass { int MemberSet(T,

int); }; template int TempClass< T, i >::MemberSet( T a, int b ) { if( ( b >= 0 ) && (b < i) ) { Tarray[b++] = a; return sizeof( a ); } else return -1; }

template <список параметров шаблона> тип_возврата имя_класса < параметры шаблона> :: имя_функции ( список параметров функции) { // тело функции }


Слайд 21В шаблоне можно использовать шаблонные функции, но функция должна быть описана

в шаблоне. template class X { public: template void mf(const U &u) { } }; int main() { } Так нельзя:
template class X { public: template void mf(const U &u); }; template template void X::mf(const U &u) { } int main() { }

Слайд 22Конструкторы и деструкторы в шаблонах
template class TempClass

{ TempClass(); ~TempClass(); }; template TempClass< T, i >::TempClass( void ) { TRACE( "TempClass created.\n" ); } template TempClass< T, i >::~TempClass( void ) { TRACE( "TempClass destroyed.\n" ); } int main() { }

Слайд 23template class MyStack { T* pStack; T StackBuffer[i];

static const int cItems = i * sizeof(T); public: MyStack( void ); void push( const T item ); T& pop( void ); }; template< class T, int i > MyStack< T, i >::MyStack( void ) { }; template< class T, int i > void MyStack< T, i >::push( const T item ) { }; template< class T, int i > T& MyStack< T, i >::pop( void ) { }; int main() { }

Слайд 24template class MyStack
{
T* pStack;

T StackBuffer[i];
public:
static const int cItems = i * sizeof(T);
MyStack( void );
void push( const T item );
T pop( void );
};

template< class T, int i > MyStack< T, i >::MyStack( void )
{
pStack = &StackBuffer[0];
};

template< class T, int i > void MyStack< T, i >::push( const T item )
{
*pStack = item;
pStack++;
};

template< class T, int i > T MyStack< T, i >::pop( void )
{
--pStack;
return *pStack;
};

int main()
{
MyStack < int, 10> mys;
for ( int i = 0; i < 6; i++)
mys.push(i);
for ( i = 0; i < 6; i++)
cout << mys.pop()<< '\n'; cout << mys.cItems;// 40

}


Слайд 25MyStack< unsigned long, 5 > stack1; // creates a stack of

// unsigned longs MyStack< DWORD, 5 > stack2; // uses code created above MyStack< char, 6 > stack3; // generates new code MyStack< MyClass, 6 > stack4; // generates stack of //MyClass objects

Слайд 26Специализация шаблона класса:
Специализация отдельного метода
Специализация класса
template < class T> void List::print();//

общий метод
void List::print();// специализированный метод

template < class T, int k = 500> class Block { };
class Block { // повторяется все тело класса
};



Слайд 27template class MyString
{
};
MyString ms;
MyString

ms_char;

template class My
{
int x;
};
template class My // специализация шаблона
{
long x;
};
template