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

Презентация:



Advertisements
Похожие презентации
Unit II Constructor Cont… Destructor Default constructor.
Advertisements

1/27 Chapter 9: Template Functions And Template Classes.
Функции с переменным числом аргументов private static int Sum(int a, int b) { return a + b; } static void Main() { int sum = Sum(1, 2); } 1 Функции.
Operator Overloading Customised behaviour of operators Chapter: 08 Lecture: 26 & 27 Date:
Преобразование типов Макаревич Л. Г.. Операция приведения типов Тип ( выражение ) Тип ( выражение ) (тип) выражение (тип) выражение int a = 5; float b.
1/30 Chapter 8: Dynamic Binding And Abstract classes.
С++. Шаблоны Сидоренко Иван. Введение Шаблоны обеспечивают поддержку обощенного программирования. Пример: template class Temp { T val; public: Temp( T);
1 A + B Операнд 1Операнд 2 Оператор Что такое выражение (expression) ? Что такое инструкция (statement) ? Операторы int max = (a > b) ? a : b;
Java Collections Framework (JCF) in Java Tutorial for students of universities Author: Oxana Dudnik.
Data Types in C. A Data Type A data type is –A set of values AND –A set of operations on those values A data type is used to –Identify the type of a variable.
A class is just a collection of variables--often of different types--combined with a set of related functions. The variables in the class are referred.
Inner Classes. 2 Simple Uses of Inner Classes Inner classes are classes defined within other classes The class that includes the inner class is called.
© Luxoft Training 2013 Java Collections API. © Luxoft Training 2013 Collections hierarchy.
1/13 Chapter 06- Implementing Operators in a class.
1 © Luxoft Training 2012 Inner and anonymous classes.
© Luxoft Training 2013 Annotations. © Luxoft Training 2013 Java reflection / RTTI // given the name of a class, get a "Class" object that // has all info.
Object Oriented Programming Ashraf Zia Lecturer Abdul Wali Khan University, Mardan. Lecture - 2.
Washington WASHINGTON UNIVERSITY IN ST LOUIS Memory Management Fred Kuhns Applied Research Laboratory, Department of Computer Science.
2005 Pearson Education, Inc. All rights reserved. 1 Object-Oriented Programming: Interface.
Object Oriented Programming Ashraf Zia Lecturer Abdul Wali Khan University, Mardan. Lecture - 1.
Транксрипт:

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

Шаблоны функций Многие алгоритмы не зависят от типов данных. Многие алгоритмы не зависят от типов данных. #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 = , b = ; char c1='a', c2 = 'f'; swap (i, j); swap (d, b); swap (c1, c2); }

template void swap_templ (T& a, T & b) { T t = a; a = b; b = t; } int main() { int i = 5, j = 6; double d = , b = ; char c1='a', c2 = 'f'; swap_templ(i,j); swap_templ(d,b); swap_templ(c1,c2); } template void f( ) { …} template void f( T& a, int k) { a = a + k; } int main() { int i = 5; f ( i, 99 ); //можно f (i,99); //будет выполнено преобразование в //double return 0; }

template 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);

Explicit 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

template void f(int c, int k) { T& a; a = a + k + c; } int main() { int i = 5; f ( i, 99 ); // ошибка return 0; } В списке параметров шаблона должны быть только классы, входящие в число входных аргументов функции В списке параметров шаблона должны быть только классы, входящие в число входных аргументов функции Тип возвращаемого значения может входить в список параметров шаблона, если такой тип есть во входных аргументах функции Тип возвращаемого значения может входить в список параметров шаблона, если такой тип есть во входных аргументах функции template 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; }

#include using namespace std; template 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 > b[i]; sort(b,n); double d[] = {22, 5, 67, 4}; sort(d,4); return 0; }

Специализированные шаблоны template 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 b[i]; sort(b,n); double d[] = {22, 5, 67, 4}; sort(d,4); return 0; }

With 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 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) {...} Дополнительные возможности задания специализированных шаблонов

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

class 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; }

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 data next; } void print_reverse() { Elem * pt = last; while ( pt ) { cout data prev; } Elem * find ( int d ) { Elem * pt = first; while ( pt ) { if ( pt->data == d ) return pt; pt = pt->next; } return NULL; }

bool 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

template имя_класса { тело класса }

template 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; }

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 data next; } void print_reverse() { Elem * pt = last; while ( pt ) { cout data prev; } Elem * find ( T d ) { Elem * pt = first; while ( pt ) { if ( pt->data == d ) return pt; pt = pt->next; } return NULL; }

bool 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 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

Использование итераторов #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 data 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

You 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 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.

Члены шаблонов template class TempClass { int MemberSet(T, int); }; template int TempClass ::MemberSet( T a, int b ) { if( ( b >= 0 ) && (b < i) ) { Tarray[b++] = a; return sizeof( a ); } else return -1; } template тип_возврата имя_класса :: имя_функции ( список параметров функции) { // тело функции }

В шаблоне можно использовать шаблонные функции, но функция должна быть описана в шаблоне. 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() { }

Конструкторы и деструкторы в шаблонах template class TempClass { TempClass(); ~TempClass(); }; template TempClass ::TempClass( void ) { TRACE( "TempClass created.\n" ); } template TempClass ::~TempClass( void ) { TRACE( "TempClass destroyed.\n" ); } int main() { }

template 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 MyStack ::MyStack( void ) { }; template void MyStack ::push( const T item ) { }; template T& MyStack ::pop( void ) { }; int main() { }

template 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 MyStack ::MyStack( void ) { pStack = &StackBuffer[0]; }; template void MyStack ::push( const T item ) { *pStack = item; pStack++; }; template T MyStack ::pop( void ) { --pStack; return *pStack; }; int main() { MyStack mys; for ( int i = 0; i < 6; i++) mys.push(i); for ( i = 0; i < 6; i++) cout

MyStack stack1; // creates a stack of // unsigned longs MyStack stack2; // uses code created above MyStack stack3; // generates new code MyStack stack4; // generates stack of //MyClass objects

Специализация шаблона класса: Специализация отдельного методаСпециализация отдельного метода Специализация классаСпециализация класса template void List ::print();// общий метод void List ::print();// специализированный метод template class Block { }; class Block { // повторяется все тело класса };

template class MyString { }; MyString ms; MyString ms_char; template class My { int x; }; template class My // специализация шаблона { long x; }; template class V> class C // параметр шаблона – // шаблон со специализацией { V y; V z; }; C c;

Использование параметра шаблона и параметра конструктора template class MyStack { T* pStack; int tek; public: MyStack( void ){tek = 0; pStack = new T[i];} void push( const T item ){pStack[tek++]=item;} T pop( void ){return pStack[--i];} }; template class MyStack { T* pStack; int tek; public: MyStack( int k = 50 ){tek = 0; pStack = new T[k];} void push( const T item ){pStack[tek++]=item;} T pop( void ){return pStack[--i];} };

template class X // или class { public: template void mf(const U &u) {U i = u; } }; int main() { X x1; x1.mf( 55); return 0; }

Правила создания шаблонов Шаблон должен лежать в h-файле Шаблон должен лежать в h-файле Отдавайте предпочтение шаблонам перед производными классами, если важно время выполнения Отдавайте предпочтение шаблонам перед производными классами, если важно время выполнения Отдавайте предпочтение производным классам перед шаблонами, если важно добавление нового кода без перекомпиляции Отдавайте предпочтение производным классам перед шаблонами, если важно добавление нового кода без перекомпиляции Отдавайте предпочтение шаблонам перед производными классами, если нельзя выделить общий базовый класс Отдавайте предпочтение шаблонам перед производными классами, если нельзя выделить общий базовый класс Шаблоны – полиморфизм времени компиляции или параметрический полиморфизм Шаблоны – полиморфизм времени компиляции или параметрический полиморфизм На шаблонах основаны библиотеки контейнерных классов, например, STL На шаблонах основаны библиотеки контейнерных классов, например, STL