• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
General Functors
 

General Functors

on

  • 765 views

 

Statistics

Views

Total Views
765
Views on SlideShare
764
Embed Views
1

Actions

Likes
0
Downloads
2
Comments
0

1 Embed 1

http://www.slideshare.net 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    General Functors General Functors Presentation Transcript

    • Generalized FUNCTORS Лозинський Ігор, Фін-3 В рамках курсу “Актуальні проблеми програмної інженерії”, 2009 р.
    • Ги-ги… Додаткова інформація: В презентації 32 сторінки Наперед перепрошую за всі лажі та недопрацювання. 
    • Майже гасло Витончені технології призначені для досягнення простоти. (original: Clever techniques should be applied for the benefit of simplicity. )
    • Що воно таке? Узагальнений функтор – це будь-який виклик процедури, що дозволений в С++ та інкапсульований в об'єкт першого класу, який гарантує типову безпеку generalized functor is any processing invocation that C++ allows, encapsulated as a typesafe first-class object Актуальні проблеми прогамної інженерії :: generalized functors 4
    • Для чого? Узагальнені функтори дозволяють зберігати виклики процедур у вигляді значень, передавати їх в якості параметрів, і виконувати іх далеко від місця створення. Суттєвою відмінністю між вказівниками на функції та узагальненими функторами в тому, що останні можуть зберігати стан об'єкта та викликати його методи. Актуальні проблеми прогамної інженерії :: generalized functors 5
    • The Command Design Pattern Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides . 1995. Design Patterns: Elements of Reusable Object-Oriented Software. Актуальні проблеми прогамної інженерії :: generalized functors 6
    • Що це дає? Модуль, що здійснює виклик не тільки не знає як виконується робота, а й не має уявлення для якого виду роботи призначений клас Command Актуальні проблеми прогамної інженерії :: generalized functors 7
    • Застосування • // Resize the window window.Resize(0, 0, 200, 100); • Command resizeCmd( window, // Object &Window::Resize, // Member function 0, 0, 200, 100); // Arguments // Later on... resizeCmd.Execute(); // Resize the window Актуальні проблеми прогамної інженерії :: generalized functors 8
    • В реальному житті • Розробка інтерфейсів користувача окремо від самих програм (skinnable) Оболонки не мають архітектури, вони лише надають місця для об'єктів класу Command Актуальні проблеми прогамної інженерії :: generalized functors 9
    • Generalized callback void Foo(); void Bar(); int main() { void (*pF)() = &Foo; Foo(); // Call Foo directly Bar(); // Call Bar directly (*pF)(); // Call Foo via pF void (*pF2)() = pF; // Create a copy of pF pF = &Bar; // Change pF to point to Bar (*pF)(); // Now call Bar via pF (*pF2)(); // Call Foo via pF2 } Актуальні проблеми прогамної інженерії :: generalized functors 10
    • Ті, що підтримують operator() (callable) • Функції • Вказівники на функції • Відсилки на функції (константні вказівники) • Функтори (об'єкти, в яких визначений operator() ) • Результати застосування операторів .* та ->* до указників на функції-члени. Актуальні проблеми прогамної інженерії :: generalized functors 11
    • Скелет Functor’а • Клас Functor має поліморфну реалізацію, але це сховано всередині нього. • Реалізація базового класу - FunctorImpl Актуальні проблеми прогамної інженерії :: generalized functors 12
    • Починаємо реалізовувати • Перша реалізація – перша проблема class Functor { public: void operator()(); // other member functions private: // implementation goes here }; Актуальні проблеми прогамної інженерії :: generalized functors 13
    • Виходить без шаблонів ніяк? template <typename ResultType> class Functor { public: ResultType operator()(); // other member functions private: // implementation }; Актуальні проблеми прогамної інженерії :: generalized functors 14
    • Ну а де аргументи? Ми не маємо морального права накладати обмеження на кількість аргументів operator()’а та на їх тип. Крім того змінних шаблонів в С++ немає. А еліпси (ellipsis) типу printf – це не красиво, та ще й небезпечно. Що робити? Актуальні проблеми прогамної інженерії :: generalized functors 15
    • Так теж не годиться // Functor with no arguments template <typename ResultType> class Functor { ... }; // Functor with one argument template <typename ResultType, typename Parm1> class Functor { ... }; Актуальні проблеми прогамної інженерії :: generalized functors 16
    • Списки типів  <typename ResultType, class TList> class Functor { ... }; Functor<double, TYPELIST_2(int, double)> myFunctor; Актуальні проблеми прогамної інженерії :: generalized functors 17
    • Але й списки не ідеальні template <typename R> class FunctorImpl<R, NullType> { public: virtual R operator()() = 0; virtual FunctorImpl* Clone() const = 0; virtual ~FunctorImpl() {} }; template <typename R, typename P1> class FunctorImpl<R, TYPELIST_1(P1)>{ public: virtual R operator()(P1) = 0; virtual FunctorImpl* Clone() const = 0; virtual ~FunctorImpl() {} }; Актуальні проблеми прогамної інженерії :: generalized functors 18
    • Сам пан Functor template <typename R, class TList> class Functor { public: Functor(); Functor(const Functor&); Functor& operator=(const Functor&); explicit Functor(std::auto_ptr<Impl> spImpl); ... private: FunctorImpl<R, TList> Impl; std::auto_ptr<Impl> spImpl_; }; Актуальні проблеми прогамної інженерії :: generalized functors 19
    • Маленька хитрість template <typename R, class TList> class Functor { typedef TList ParmList; typedef typename TypeAtNonStrict<TList, 0, EmptyType>::Result Parm1; typedef typename TypeAtNonStrict<TList, 1, EmptyType>::Result Parm2; ... as above ... }; • Доступаємось до типу, знаючи його номер (дивно, але працює  ) Актуальні проблеми прогамної інженерії :: generalized functors 20
    • Реалізація operator()’а template <typename R, class TList> class Functor { ... as above ... public: R operator()() { return (*spImpl_)(); } R operator()(Parm1 p1) { return (*spImpl_)(p1); } R operator()(Parm1 p1, Parm2 p2) { return (*spImpl_)(p1, p2); } }; Актуальні проблеми прогамної інженерії :: generalized functors 21
    • В чому фокус? Functor<double, TYPELIST_2(int, double)> myFunctor; double result = myFunctor(4, 5.6); // Wrong invocation. double result = myFunctor(); Актуальні проблеми прогамної інженерії :: generalized functors 22
    • Робота з функторами template <typename R, class TList> class Functor { ... as above ... public: template <class Fun> Functor(const Fun& fun); }; • Таким чином ми доступатимемось до інших функторів Актуальні проблеми прогамної інженерії :: generalized functors 23
    • Так багато коду для одного конструктора template <class ParentFunctor, typename Fun> class FunctorHandler : public FunctorImpl < typename ParentFunctor::ResultType, typename ParentFunctor::ParmList > { public: typedef typename ParentFunctor::ResultType ResultType; … Актуальні проблеми прогамної інженерії :: generalized functors 24
    • … готуємо конструктор FunctorHandler(const Fun& fun) : fun_(fun) {} FunctorHandler* Clone() const { return new FunctorHandler(*this); } ResultType operator()() { return fun_(); } ResultType operator()(typename ParentFunctor::Parm1 p1) { return fun_(p1); } ResultType operator()(typename ParentFunctor::Parm1 p1, typename ParentFunctor::Parm2 p2){ return fun_(p1, p2); } private: Fun fun_; }; Актуальні проблеми прогамної інженерії :: generalized functors 25
    • Нарешті вимучили наш конструктор template <typename R, class TList> template <typename Fun> Functor<R, TList>::Functor(const Fun& fun) : spImpl_(new FunctorHandler<Functor, Fun>(fun)); {} • Ще один трюк – шаблонне визначення члена поза межами класу (quot;out-of-class member template definition.quot; ) Актуальні проблеми прогамної інженерії :: generalized functors 26
    • Тестуємо – все красиво #include “Functor.h” #include <iostream> struct TestFunctor { void operator()(int i, double d) { cout <<quot;TestFunctor::operator()(quot; << i << quot;, quot; << d << quot;) called.nquot;; } }; int main() { TestFunctor f; Functor<void, TYPELIST_2(int, double)> cmd(f); cmd(4, 4.5); } Актуальні проблеми прогамної інженерії :: generalized functors 27
    • Не просто красиво – дуже красиво • Працюємо з функторами • Працюємо з функціями • Автоматично зводимо типи аргументів та результатів (все й справді чесно) (приклад: char* -> string) Актуальні проблеми прогамної інженерії :: generalized functors 28
    • Вказівники на методи об'єктів • Є певні нюанси (але вони дещо виходять за межі нашого обговорення, та й для чого ускладнювати?) • Реалізується тим же шляхом що й FunctorHandler Актуальні проблеми прогамної інженерії :: generalized functors 29
    • Бонуси • Зв'язування певних атрибутів (до початку виклику ми не тільки вкажемо на виконавця, але й задамо атрибути виконання, тобто певне описання середовища, в якому відбувається робота ). • Ланцюжок – (MacroCommand, з Gamma et al*, 1995) - дозволяє створювати пакет виконання команд. Всі команди на момент “запаковування” повинні бути зв'язаними. Проте пізніше однією командою можна запустити цілу програму, створену на етапі виконання. * Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides . 1995. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley. Актуальні проблеми прогамної інженерії :: generalized functors 30
    • Де це знайти? • loki • Посилання: http://sourceforge.net/projects/loki-lib • Для презентації використовувалась версія 0.1.7 Актуальні проблеми прогамної інженерії :: generalized functors 31
    • Ніби кінець… • Спасибі за увагу • Буду вдячний, якщо питання Ви не задаватимете.  Актуальні проблеми прогамної інженерії :: generalized functors 32