C++ templates. Синтаксис template void f(const T& value) { std::cout << "Value is: " << value << std::endl; } template struct Array { T data[n]; };

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



Advertisements
Похожие презентации
Функции с переменным числом аргументов private static int Sum(int a, int b) { return a + b; } static void Main() { int sum = Sum(1, 2); } 1 Функции.
Advertisements

Язык C++ Лекция 2. Недостатки enumов Засорение namespaceа, в котором находится enum Соответственно, члены enumа должны иметь уникальный префикс.
С++. Шаблоны Сидоренко Иван. Введение Шаблоны обеспечивают поддержку обощенного программирования. Пример: template class Temp { T val; public: Temp( T);
Шаблоны в С++ Макаревич Л. Г.. Шаблоны функций Многие алгоритмы не зависят от типов данных. Многие алгоритмы не зависят от типов данных. #include using.
1 A + B Операнд 1Операнд 2 Оператор Что такое выражение (expression) ? Что такое инструкция (statement) ? Операторы int max = (a > b) ? a : b;
Преобразование типов Макаревич Л. Г.. Операция приведения типов Тип ( выражение ) Тип ( выражение ) (тип) выражение (тип) выражение int a = 5; float b.
Исключения как механизм обработки ошибок Варианты обработки ошибок без исключений: 1.Умолчание ошибки int atoi ( const char * str ); const char * strVal.
Прикладное программирование кафедра прикладной и компьютерной оптики Полиморфизм.
Объектно-ориентированное программирование С++. Лекция 8 Карпов В.Э.
Class Date { private int year = 0; private int month = 0; private int day = 0; public void SetDate (int y, int m, int d) { year = y; month = m; day = d;
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Test 10 Вопрос 1. public class Test implements Iterator { // 1 private List list = new ArrayList (); // 2 public void addList(T... ts) { Collections.addAll(list,
Unit II Constructor Cont… Destructor Default constructor.
Обработка исключений Основы метапрограммированияОбработка исключений Основы метапрограммирования.
1/30 Chapter 8: Dynamic Binding And Abstract classes.
Test 4 Вопрос 1. public class TestOutput { public static void main(String[] args) throws IOException { PrintStream out = new PrintStream( new BufferedOutputStream(
В. М. Гуровиц, Глобальные функции объявляются в самой программе или в модуле и доступны из любого места программы Локальные функции.
1. Классы ООП 1.Наследование 2.Инкапсуляция 3.Полиморфизм.
Статические поля класса Статические поля хранят данные, общие для всех элементов класса. Статическое поле существует в единственном экземпляре для всех.
1/27 Chapter 9: Template Functions And Template Classes.
Транксрипт:

C++ templates

Синтаксис template void f(const T& value) { std::cout

Примеры использования template class auto_ptr { typedef auto_ptr MyType; T* _ptr; auto_ptr(const MyType& other); MyType& operator = (const MyType& other); public: auto_ptr(T* const ptr) : _ptr(ptr) { } ~auto_ptr() { delete _ptr; } T& operator *() const { return *_ptr; } T* operator ->() const { return _ptr; } };

Примеры использования struct A { int a; }; int main() { auto_ptr p_a = new A; (*p_a).a = 9; int i = p_a->a; return 0; }

smart pointers std::auto_ptr – лучше не использовать _com_ptr_t – для COM-интерфейсов boost::scoped_ptr – некопируемый boost::shared_ptr – копируемый, использует подсчёт ссылок boost::weak_ptr – решает проблему «кольцевых ссылок»

boost:: scoped_ptr template class scoped_ptr // noncopyable { T * ptr; scoped_ptr(scoped_ptr const &); // prohibited scoped_ptr & operator=(scoped_ptr const &); // prohibited void operator==( scoped_ptr const& ) const; // prohibited void operator!=( scoped_ptr const& ) const; // prohibited public: explicit scoped_ptr(T * p = 0); // never throws explicit scoped_ptr(std::auto_ptr p); // never throws ~scoped_ptr(); // never throws T & operator*() const; // never throws T * operator->() const; // never throws operator bool () const; // never throws bool operator! () const; // never throws T * get() const; // never throws void reset(T * p = 0); // never throws void swap(scoped_ptr & b); // never throws };

std::auto_ptr template class auto_ptr { public: template operator auto_ptr () { return (auto_ptr (*this)); } template auto_ptr & operator = (auto_ptr & _Right) { reset(_Right.release()); return (*this); } template auto_ptr(auto_ptr & _Right) : _Myptr(_Right.release()) {} _Ty *release() { _Ty *_Tmp = (_Ty *)_Myptr; _Myptr = 0; return (_Tmp); }... };

Недостатки глобальных переменных Объекты создаются всегда, даже если они не используются Порядок инициализации в общем случае неизвестен Объекты не разрушаются до завершения программы Проблемы с исключениями в конструкторах объектов

Singleton template class Singleton { public: static T& Instance() { static T instance; return instance; } static const T& ConstInstance() { return const_cast (Instance()); } };

Singleton class A { private: friend class Singleton ; A() {} public: int a; }; int main() { Singleton ::Instance().a = 3; std::cout ::ConstInstance().a

Частичная специализация шаблонов template T MaxValue(); template int MaxValue () { return INT_MAX; } template float MaxValue () { return FLT_MAX; } int main() { std::cout ()

Compile time check template struct CompileTimeError; template struct CompileTimeError {}; CompileTimeError ERROR_assert_failed; #define STATIC_CHECK(expr, msg) \ { CompileTimeError ERROR_##msg; (void)ERROR_##msg; } int main() { STATIC_CHECK(2 == 5, assert_failed) return 0; }

Шаблонные шаблонные параметры template class Creator = NewCreator > class Singleton { public: typedef T* InstancePtr; private: static InstancePtr _instancePtr; static void Destroy(void) { if(_instancePtr != NULL) Creator ::Destroy(_instancePtr); } public: static T& Instance() { if(_instancePtr == NULL) { _instancePtr = Creator ::Create(); atexit(&Singleton::Destroy); } return *_instancePtr; } }; template class C> typename Singleton ::InstancePtr Singleton ::_instancePtr = NULL;

Шаблонные шаблонные параметры template struct MallocCreator { static T* Create() { void* p = std::malloc(sizeof(T)); if (!p) return 0; return new(p) T; } static void Destroy(T* p) { p->~T(); std::free(p); } }; template struct NewCreator { static T* Create() { return new T; } static void Destroy(T* p) { delete p; } };

Недостатки указателей на функции Нет информации о типах аргументов и возвращаемого значения Указатель на функцию необходимо перед вызовом проверять на NULL Есть возможность привести указатель на функцию к любому указателю Разный синтаксис вызова для указателей на функции и указателей на методы

Функторы, простая реализация template class function; template class function { typedef function MyType; typedef R (*Signature)(P); Signature _func; MyType& operator = (const MyType&); public: function(Signature func) : _func(func) { } function(const MyType& other): _func(other._func) { } R operator () (P p) { return _func(p); } };

Функторы, простая реализация template class function { typedef function MyType; typedef R (ObjType::*Signature)(P1, P2); Signature _func; MyType& operator = (const MyType&); public: function(Signature func) : _func(func) { } function(const MyType& other): _func(other._func) { } R operator () (ObjType& obj, P1 p1, P2 p2) { return (obj.*_func)(p1, p2); } };

Функторы, простая реализация struct A { char C; A(char c = X') : C(c) { } void member_func(double i, bool b) { if (b) std::cout

Функторы STL int main() { A a; std::mem_fun1_t f = std::mem_fun(&A::member_func); f(&a, 0.5); std::mem_fun1_ref_t f_ref = std::mem_fun_ref(&A::member_func); f_ref(a, 0.7); std::pointer_to_unary_function f2 = std::ptr_fun(&abs); std::cout

Недостатки функторов STL Уродливый синтаксис Отсутствие функторов с большим количеством параметров Отсутствует возможность инициализации функтора с сигнатурой func1 указателем на func2: struct B : public A{}; void func1(B*); void func2(A*);

boost::function int main() { A a; boost::function f = &A::member_func; f(a, 0.5); boost::function f2 = &abs; std::cout

Применение функторов void generate_int(int& i) { i = rand() % ; } void print_int(int i) { std::cout

Привязывание параметров int main() { std::vector vec(10); std::for_each(vec.begin(), vec.end(), &generate_int); std::for_each(vec.begin(), vec.end(), &print_int); std::cout

Недостатки std::bind1st/2nd Работают только для binary_function Привязывают только один аргумент Неудобный синтаксис Нет возможности привязать ссылку: void inc (int& n, bool) { ++n; } //... std::bind1st(std::ptr_fun(&inc), i) (true);

boost::bind bool in_range( int min_val, int max_val, int val ) { return (val >= min_val) && (val

Подводные камни boost::bind class WindowBase { typedef boost::function EventHandler; EventHandler _onPaint; protected: WindowBase(const EventHandler& onPaint) : _onPaint(onPaint) { } //... }; struct MyWindow : public WindowBase { MyWindow() : WindowBase(boost::bind(&MyWindow::OnPaint, this)) { } void OnPaint() { } }; MyWindow CreateMyGreatWindow() { return MyWindow(); } int main() { MyWindow wnd = CreateMyGreatWindow(); return 0; }

Преимущества использования шаблонов C++ Шаблоны решают проблему дублирования кода Зачастую шаблоны позволяют избавиться от динамической диспечеризации и повысить скорость работы приложения Позволяют отследить большую часть ошибок на этапе компиляции Использование стратегий позволяет не писать сложные классы с нуля, а собирать их из множества меньших Можно грабить корованы

Список литературы Бьерн Страуструп. Язык программирования С++ Скотт Мейерс. Эффективное использование С++ Скотт Мейерс. Наиболее эффективное использование С++ Скотт Мейерс. Эффективное использование STL Герб Саттер. Решение сложных задач на C++ Герб Саттер. Новые сложные задачи на C++ Андрей Александреску. Современное проектирование на C++ Герб Саттер. Андрей Александреску. Стандарты программирования на С правило и рекомендация Владимир Сорокин. Голубое сало.