C++ templates презентация

Содержание

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

Слайд 1C++ templates


Слайд 2Синтаксис
template < typename T >
void f(const T& value)
{
std::cout

"Value is: " << value << std::endl;
}

template < typename T, size_t n >
struct Array
{
T data[n];
};

Слайд 3Примеры использования
template < typename T >
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; }
};

Слайд 4Примеры использования
struct A
{
int a;
};


int main()
{
auto_ptr p_a = new A;
(*p_a).a =

9;
int i = p_a->a;

return 0;
}

Слайд 5smart pointers
std::auto_ptr – лучше не использовать

_com_ptr_t – для COM-интерфейсов

boost::scoped_ptr – некопируемый
boost::shared_ptr

– копируемый, использует подсчёт ссылок
boost::weak_ptr – решает проблему «кольцевых ссылок»


Слайд 6boost:: 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
};

Слайд 7std::auto_ptr
template < class _Ty > class auto_ptr
{
public:
template operator auto_ptr()
{ return

(auto_ptr<_Other>(*this)); }

template auto_ptr<_Ty>& operator = (auto_ptr<_Other>& _Right)
{ reset(_Right.release()); return (*this); }

template auto_ptr(auto_ptr<_Other>& _Right) : _Myptr(_Right.release())
{}

_Ty *release()
{
_Ty *_Tmp = (_Ty *)_Myptr;
_Myptr = 0;
return (_Tmp);
}

...
};

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

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



Слайд 9Singleton
template < typename T >
class Singleton
{
public:
static T& Instance()
{
static T instance;
return

instance;
}

static const T& ConstInstance()
{
return const_cast(Instance());
}
};

Слайд 10Singleton
class A
{
private:
friend class Singleton;
A() {}

public:
int a;
};

int main()
{
Singleton::Instance().a = 3;
std::cout

<< std::endl;
return 0;
}

Слайд 11Частичная специализация шаблонов
template < typename T >
T MaxValue();

template < >
int

MaxValue()
{ return INT_MAX; }

template < >
float MaxValue()
{ return FLT_MAX; }

int main()
{
std::cout << "Max int value = " << MaxValue() << std::endl;
std::cout << "Max float value = " << MaxValue() << std::endl;
return 0;
}

Слайд 12Compile time check
template struct CompileTimeError;
template struct CompileTimeError{};

CompileTimeError

4> ERROR_assert_failed;

#define STATIC_CHECK(expr, msg) \
{ CompileTimeError ERROR_##msg; (void)ERROR_##msg; }


int main()
{
STATIC_CHECK(2 == 5, assert_failed)
return 0;
}

Слайд 13Шаблонные шаблонные параметры
template < typename T, 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 < typename T, template class C>
typename Singleton::InstancePtr Singleton::_instancePtr = NULL;

Слайд 14Шаблонные шаблонные параметры
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; }
};

Слайд 15Недостатки указателей на функции
Нет информации о типах аргументов и возвращаемого значения
Указатель

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


Слайд 16Функторы, простая реализация
template < typename Signature >
class function;

template < typename R,

typename P >
class function < R (P) >
{
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); }
};

Слайд 17Функторы, простая реализация
template
class

function < R (ObjType::*) (P1, P2) >
{
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); }
};

Слайд 18Функторы, простая реализация
struct A
{
char C;

A(char c = ‘X') : C(c) {

}

void member_func(double i, bool b)
{ if (b) std::cout << C << i << std::endl; }
};

int main()
{
A a;

function< void (A::*)(double, bool) > f(&A::member_func);
f(a, 0.5, true);

function < int (int) > f2(&abs);
std::cout << f2(-123) << std::endl;

return 0;
}

Слайд 19Функторы STL

int main()
{
A a;
std::mem_fun1_t< void, A, double > f = std::mem_fun(&A::member_func);
f(&a,

0.5);

std::mem_fun1_ref_t < void, A, double > 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 << f2(-123) << std::endl;

return 0;
}

Слайд 20Недостатки функторов STL
Уродливый синтаксис
Отсутствие функторов с большим количеством параметров
Отсутствует возможность инициализации

функтора с сигнатурой func1 указателем на func2:
struct B : public A{};

void func1(B*);
void func2(A*);

Слайд 21boost::function
int main()
{
A a;
boost::function < void (A&, double) > f = &A::member_func;
f(a,

0.5);

boost::function < int (int) > f2 = &abs;
std::cout << f2(-123) << std::endl;

return 0;
}

Слайд 22Применение функторов
void generate_int(int& i)
{ i = rand() % 100 - 50;

}

void print_int(int i)
{ std::cout << i << " "; }

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::endl;

std::vector out_vec;
std::transform(vec.begin(), vec.end(), std::back_inserter(out_vec), &abs);
std::for_each(out_vec.begin(), out_vec.end(), &print_int);
std::cout << std::endl;

return 0;
}

Слайд 23Привязывание параметров
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

vec.end(),
std::bind1st(std::less(), 10)), vec.end() );

std::for_each(vec.begin(), vec.end(), &print_int);
std::cout << std::endl;

return 0;
}

Слайд 24Недостатки std::bind1st/2nd
Работают только для binary_function
Привязывают только один аргумент
Неудобный синтаксис
Нет возможности привязать

ссылку:
void inc (int& n, bool) { ++n; }
// ...
std::bind1st(std::ptr_fun(&inc), i) (true);

Слайд 25boost::bind
bool in_range( int min_val, int max_val, int val )
{ return (val

>= min_val) && (val <= max_val); }

int main()
{
// ...

boost::function < bool(int) > pred = boost::bind(&in_range, 5, 15, _1);
vec.erase( std::remove_if(vec.begin(), vec.end(), pred), vec.end() );

// ...

return 0;
}

Слайд 26“Подводные камни” boost::bind
class WindowBase
{
typedef boost::function < void (void) > 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;
}

Слайд 27Преимущества использования шаблонов C++
Шаблоны решают проблему дублирования кода
Зачастую шаблоны позволяют избавиться

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

Слайд 28Список литературы
Бьерн Страуструп. Язык программирования С++
Скотт Мейерс. Эффективное использование С++
Скотт Мейерс.

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

Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика