МЕТОДИ ОБ'ЄКТНО-
       ОРІЄНТОВАНОГО
       ПРОГРАМУВАННЯ - 2007
        Бублик В.В.
        Кафедра мультимедійних систе...
Тема 6.
Узагальнене програмування


  Корисно повторити:
  Об'єктне програмування.
  Лекція 8. Параметризовані класи



  ...
Динамічний поліморфізм


  Чи завжди він потрібен?




                            3
Динамічний поліморфізм
Пізнє зв'язування віртуальних функцій
  вимагає
 Ієрархії класів
 Дотримання дисципліни
   стабі...
Поліморфна ієрархія класів
Базовий клас
      class Base {
      public:
         virtual void vf() {
                ...
Поліморфна ієрархія класів
Похідний клас
      class Derived: public Base {
      public:
         virtual void vf() {
...
Заміщення при пізньому
зв'язуванні
 void manipulator(Base & x){
    x.f();
    x.g(); }

 Base b;
 Derived d;

 mani...
Накладні витрати поліморфізму
    x.f();   //   виклик віртуальної функції
    00401207 mov     edx,dword ptr [ebp+8]
 ...
Внесення стабільного інтерфейсу
Базовий клас
    class NVIBase {
    public:
        void vf() {
                dovf(...
Внесення стабільного інтерфейсу
Похідний клас
 class NVIDerived: public NVIBase
{
 private:
    virtual void dovf() {
...
Накладні витрати невіртуального
інтерфейсу
 Без особливих додаткових накладних
  витрат: один зайвий виклик
  невіртуальн...
Виділення абстрактного
нетермінального класу
Базовий клас
    class NVINTBase {
    public:
        void vf() {
      ...
Виділення абстрактного
нетермінального класу
Похідні класи
 class NVITBase: public NVINTBase
 {};

 class NVITDerived: ...
Порівняння викликів деструкторів
Виклик невіртуального деструктора
 delete nvip;
    0043771D          mov              ...
Порівняння викликів деструкторів
Накладні витрати віртуального деструктора
    delete pb;
    00437780     mov     eax,d...
Висновок
 Повна гнучкість рішень за рахунок
  динамічного розпізнавання типу
  об'єкту при значних затратах як на
  етапі...
“Невіртуальна” ієрархія
 class Base {
 public:
    void f() {cout<<quot;Base::f()quot;<<endl; }
    void g() {cout<<qu...
Раннє зв'язування
 void manipulator(Base & x){
    x.f();
    x.g(); }

 Base b;
 Derived d;

 manipulator(b);      ...
Висновок
 Раннє зв'язування не забезпечує
  заміщень: при підстановці параметром
  об'єкту похідного класу викликаються
 ...
Узагальнений маніпулятор ієрархією
класів
 template <typename T>
 void manipulator(T & x){
    x.f();
    x.g(); }

 ...
Висновок
 Шаблон, застосований до ієрархії,
  доповненої явним делегуванням,
  моделює статичний поліморфізм




 © 2006 ...
“На городі бузина...”
    class ElderBerry        // бузина
    {
    public:
       void f(char a='!', double x=1, bo...
А де Murgatroyd?
    class Murgatroyd {
    public:
        void f() {
                cout<<quot;Murgatroyd::f()quot;...
Узагальнена функція
 template <class T>
 void manipulator(T & x){
    x.f();
    x.g(); }

 ElderBerry u;
 Murgatroy...
Поліморфізм без ієрархії
 Методи узагальненого
  програмування дозволяють
  промоделювати статичний
  поліморфізм не заст...
Висновок
 Кожен початківець хоче
  продемонструвати володіння
  успадкуванням (90% випадків)
 Віртуальні функції найчаст...
Безпечність узагальненого
програмування

  Наперед невідомо, який саме тип буде
  підставлено до шаблону: як гарантувати
 ...
Синтаксичний контроль типів
1.   Успадкування типів
2.   Зведення типів
3.   Примітивність типів
4.   Індексованість типів...
Типізація (за Бучем)
 Засіб захисту від
  використання
  об’єктів одного
  класу замість
  іншого, або
  принаймні спосіб...
Шаблон з одним параметром
 Пробуємо розмістити значення
 Того ж типу Т на новому місці

    template <class T>
    voi...
Застосування шаблону
 void converted( double*& p1, Base* p2 ) {
    Base b;
    Derived d;

      construct( p1, 2.718...
Результати першої спроби
 void converted( double*& p1, Base* p2 ) {
    Base b;
    Derived d;

    construct( p1, 2.7...
Висновок
(з першої спроби)
 Надто жорстка умова на типовий
   параметр




 © 2006 Бублик В.В. МООП-9. Узагальнене програ...
Шаблон з двома параметрами
 Пробуємо розмістити значення типу Т2
 на новому місці за указником типу Т1
 Як уникнути нед...
Обмеження на успадкування
    template <class Base, class Derived>
    struct must_have_base
    {
        ~must_have_...
Шаблон, доповнений перевіркою
підтипів
 Спроба використати недопустиму
 комбінацію типів діагностується компілятором

 ...
Результати другої спроби
 void converted( double*& p1, Base* p2 ) {
    Base b;
    Derived d;

    construct( p1, 2.7...
Обмеження на зводимість
    template <class Type, class Convert>
    struct must_be_converted
    {
       ~must_be_co...
Шаблон, доповнений перевіркою
зведення типів
 Спроба використати недопустиму
 комбінацію типів діагностується компілятор...
Результати третьої спроби
 void converted( double*& p1, Base* p2 ) {
    Base b;
    Derived d;

      construct( p1, ...
Перевірка примітивності типу
    template <class T>
    struct must_be_POD
    {
       ~must_be_POD()
       {
    ...
Приклади інших перевірок




                           42
Перевірка індексованості
    template <class T>
    struct must_be_subscriptable
    {
       ~must_be_subscriptable()...
Перевірка розмірностей
    template <class T1, class T2>
    struct must_have_same_size
    {
       ~must_have_same_s...
Висновок
 Збалансовуйте застосування
  успадкувань і шаблонів
 Зважено контролюйте типи, але не
  вимагайте від них біль...
Upcoming SlideShare
Loading in...5
×

Templates

723

Published on

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
723
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Templates "

  1. 1. МЕТОДИ ОБ'ЄКТНО- ОРІЄНТОВАНОГО ПРОГРАМУВАННЯ - 2007 Бублик В.В. Кафедра мультимедійних систем, кімн. 204/1 Консультації: вівторок, середа ! 15-16 год. me lco we http://emerecu.ukma.kiev.ua/efolio are ou Y S tokh lm c o , 1 Ku ngligaT e kaH ö ko knis gs lan
  2. 2. Тема 6. Узагальнене програмування Корисно повторити: Об'єктне програмування. Лекція 8. Параметризовані класи 2
  3. 3. Динамічний поліморфізм Чи завжди він потрібен? 3
  4. 4. Динамічний поліморфізм Пізнє зв'язування віртуальних функцій вимагає  Ієрархії класів  Дотримання дисципліни  стабільного інтерфейсу  нетермінальних класів  Накладних витрат непрямого виклику © 2006 Бублик В.В. МООП-9. Узагальнене програмування 4 (45)
  5. 5. Поліморфна ієрархія класів Базовий клас  class Base {  public:  virtual void vf() {  cout<<quot;Base::f()quot;<<endl; }  void g() {  cout<<quot;Base::g()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 5 (45)
  6. 6. Поліморфна ієрархія класів Похідний клас  class Derived: public Base {  public:  virtual void vf() {  cout<<quot; Derived ::f()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 6 (45)
  7. 7. Заміщення при пізньому зв'язуванні  void manipulator(Base & x){  x.f();  x.g(); }  Base b;  Derived d;  manipulator(b); //Base::f();Base::g()  manipulator(d); //Derived:: f();Base::g() © 2006 Бублик В.В. МООП-9. Узагальнене програмування 7 (45)
  8. 8. Накладні витрати поліморфізму  x.f(); // виклик віртуальної функції  00401207 mov edx,dword ptr [ebp+8]  0040120A mov eax,dword ptr [edx]  0040120C mov esi,esp  0040120E mov ecx,dword ptr [ebp+8]  00401211 call dword ptr [eax]  00401213 cmp esi,esp  00401215 call __chkesp (00409620)  0040121A  x.g(); // виклик невіртуальної функції  00401700 mov ecx,dword ptr [ebp+8]  00401703 call @ILT+805(Base::g) (0040132a)  00401708 © 2006 Бублик В.В. МООП-9. Узагальнене програмування 8 (45)
  9. 9. Внесення стабільного інтерфейсу Базовий клас  class NVIBase {  public:  void vf() {  dovf(); return;}  void g() {  cout<<quot;Base::g()quot;<<endl; }  private:  virtual void dovf() {  cout<<quot;Base::f()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 9 (45)
  10. 10. Внесення стабільного інтерфейсу Похідний клас  class NVIDerived: public NVIBase {  private:  virtual void dovf() {  cout<<quot; Derived ::f()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 10 (45)
  11. 11. Накладні витрати невіртуального інтерфейсу  Без особливих додаткових накладних витрат: один зайвий виклик невіртуальної інтерфейсної функції  x.vf();  00416E5E mov ecx,dword ptr [x]  00416E61 call NVIBase::vf (415EFBh) © 2006 Бублик В.В. МООП-9. Узагальнене програмування 11 (45)
  12. 12. Виділення абстрактного нетермінального класу Базовий клас  class NVINTBase {  public:  void vf() {  dovf(); return;}  void g() {  cout<<quot;Base::g()quot;<<endl; }  virtual ~NVINTBase()=0;  private:  virtual void dovf() {  cout<<quot;Base::f()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 12 (45)
  13. 13. Виділення абстрактного нетермінального класу Похідні класи  class NVITBase: public NVINTBase  {};  class NVITDerived: public NVINTBase {  private:  virtual void dovf() {  cout<<quot; Derived ::f()quot;<<endl; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 13 (45)
  14. 14. Порівняння викликів деструкторів Виклик невіртуального деструктора  delete nvip;  0043771D mov eax,dword ptr [nvip]  00437720 mov dword ptr [ebp-158h],eax  00437726 mov ecx,dword ptr [ebp-158h]  0043772C push ecx  0043772D call operator delete (41550Fh)  00437732 add esp,4 © 2006 Бублик В.В. МООП-9. Узагальнене програмування 14 (45)
  15. 15. Порівняння викликів деструкторів Накладні витрати віртуального деструктора  delete pb;  00437780 mov eax,dword ptr [pb]  00437783 mov dword ptr [ebp-134h],eax  00437789 mov ecx,dword ptr [ebp-134h]  0043778F mov dword ptr [ebp-140h],ecx  00437795 cmp dword ptr [ebp-140h],0  0043779C je main+151h (4377C1h)  0043779E mov esi,esp  004377A0 push 1  004377A2 mov edx,dword ptr [ebp-140h]  004377A8 mov eax,dword ptr [edx]  004377AA mov ecx,dword ptr [ebp-140h]  004377B0 call dword ptr [eax]  004377B2 cmp esi,esp  004377B4 call @ILT+2795(__RTC_CheckEsp) (415AF0h)  004377B9 mov dword ptr [ebp-16Ch],eax  004377BF jmp main+15Bh (4377CBh)  004377C1 mov dword ptr [ebp-16Ch],0 © 2006 Бублик В.В. МООП-9. Узагальнене програмування 15 (45)
  16. 16. Висновок  Повна гнучкість рішень за рахунок динамічного розпізнавання типу об'єкту при значних затратах як на етапі програмування, так і виконання © 2006 Бублик В.В. МООП-9. Узагальнене програмування 16 (45)
  17. 17. “Невіртуальна” ієрархія  class Base {  public:  void f() {cout<<quot;Base::f()quot;<<endl; }  void g() {cout<<quot;Base::g()quot;<<endl; }  };  class Derived : public Base {  public:  void f() {cout<<quot; Derived::f()quot;<<endl; }  // пряме відсилання до базового класу  void g() {Base::g();}  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 17 (45)
  18. 18. Раннє зв'язування  void manipulator(Base & x){  x.f();  x.g(); }  Base b;  Derived d;  manipulator(b); //Base::f();Base::g()  manipulator(d); // Base::f();Base::g() © 2006 Бублик В.В. МООП-9. Узагальнене програмування 18 (45)
  19. 19. Висновок  Раннє зв'язування не забезпечує заміщень: при підстановці параметром об'єкту похідного класу викликаються функції базового © 2006 Бублик В.В. МООП-9. Узагальнене програмування 19 (45)
  20. 20. Узагальнений маніпулятор ієрархією класів  template <typename T>  void manipulator(T & x){  x.f();  x.g(); }  Base b;  Derived d;  manipulator(b); //Base::f();Base::g()  manipulator(d); //Derived:: f();Base::g() © 2006 Бублик В.В. МООП-9. Узагальнене програмування 20 (45)
  21. 21. Висновок  Шаблон, застосований до ієрархії, доповненої явним делегуванням, моделює статичний поліморфізм © 2006 Бублик В.В. МООП-9. Узагальнене програмування 21 (45)
  22. 22. “На городі бузина...”  class ElderBerry // бузина  {  public:  void f(char a='!', double x=1, bool t=true)  {  cout<<quot;ElderBerry::f()quot;<<endl;  }  void g(char a='?')  {  cout<<quot;ElderBerry::g()quot;<<endl;  }  void goToUncle(); // у Києві  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 22 (45)
  23. 23. А де Murgatroyd?  class Murgatroyd {  public:  void f() {  cout<<quot;Murgatroyd::f()quot;<<endl;  }  void g(ElderBerry & ga=ElderBerry(),  double a=3.14) {  cout<<quot; ElderBerry::g()quot;<<endl;  ga.g();  }  // An exclamation of surprise  int heavensTo(const Murgatroyd &);  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 23 (45)
  24. 24. Узагальнена функція  template <class T>  void manipulator(T & x){  x.f();  x.g(); }  ElderBerry u;  Murgatroyd v;  manipulator(u); // ElderBerry::f(), ElderBerry:: g()  manipulator(v); // Murgatroyd ::f(), ElderBerry:: g() © 2006 Бублик В.В. МООП-9. Узагальнене програмування 24 (45)
  25. 25. Поліморфізм без ієрархії  Методи узагальненого програмування дозволяють промоделювати статичний поліморфізм не застосовуючи ієрархії класів, а лише їх знайомств за умови узгодженості їх поведінки © 2006 Бублик В.В. МООП-9. Узагальнене програмування 25 (45)
  26. 26. Висновок  Кожен початківець хоче продемонструвати володіння успадкуванням (90% випадків)  Віртуальні функції найчастіше вживаються некоректно  Застосовувати динамічний поліморфізм варто лише тоді, коли статичного не вистачає  Узагальнене програмування найпотужніший механізм статичного поліморфізму, але... © 2006 Бублик В.В. МООП-9. Узагальнене програмування 26 (45)
  27. 27. Безпечність узагальненого програмування Наперед невідомо, який саме тип буде підставлено до шаблону: як гарантувати працездатність за мінімальних вимог до типового параметру? Як уникнути збоїв на етапі виконання? 27
  28. 28. Синтаксичний контроль типів 1. Успадкування типів 2. Зведення типів 3. Примітивність типів 4. Індексованість типів © 2006 Бублик В.В. МООП-9. Узагальнене програмування 28 (45)
  29. 29. Типізація (за Бучем)  Засіб захисту від використання об’єктів одного класу замість іншого, або принаймні спосіб управління цим використанням. © 2006 Бублик В.В. МООП-9. Узагальнене програмування 29 (45)
  30. 30. Шаблон з одним параметром  Пробуємо розмістити значення  Того ж типу Т на новому місці  template <class T>  void construct( T*& p, const T& value )  {  p =new T(value);  return;  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 30 (45)
  31. 31. Застосування шаблону  void converted( double*& p1, Base* p2 ) {  Base b;  Derived d;  construct( p1, 2.718 );  construct( p2, b );  construct( p1, 42 );  construct<double>( p1, 42 );   construct( p2, d );  construct<Base>( p2, d );  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 31 (45)
  32. 32. Результати першої спроби  void converted( double*& p1, Base* p2 ) {  Base b;  Derived d;  construct( p1, 2.718 );  construct( p2, b );  // construct( p1, 42 ); 42 is int  construct<double>( p1, 42 );   // construct( p2, d ); d is Derived  construct<Base>( p2, d );  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 32 (45)
  33. 33. Висновок (з першої спроби)  Надто жорстка умова на типовий параметр © 2006 Бублик В.В. МООП-9. Узагальнене програмування 33 (45)
  34. 34. Шаблон з двома параметрами  Пробуємо розмістити значення типу Т2  на новому місці за указником типу Т1  Як уникнути недопустимих комбінацій типів  template <class T1, class T2>  void construct( T1*& p, const T2& value )  {  p =new T2(value);  return;  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 34 (45)
  35. 35. Обмеження на успадкування  template <class Base, class Derived>  struct must_have_base  {  ~must_have_base()  {  void (*p)(Derived*, Base*) = constraints;  }  private:  static void constraints(Derived* pd, Base* pb)  {  pb=pd;  }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 35 (45)
  36. 36. Шаблон, доповнений перевіркою підтипів  Спроба використати недопустиму  комбінацію типів діагностується компілятором  template <class T1, class T2>  void construct( T1*& p, const T2& value )  {  must_have_base<T1, T2> check;  p =new T2(value);  return;  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 36 (45)
  37. 37. Результати другої спроби  void converted( double*& p1, Base* p2 ) {  Base b;  Derived d;  construct( p1, 2.718 );  construct( p2, b );  // construct( p1, 42 ); 42 is int  // construct<double>( p1, 42 ); не підтип   construct( p2, d ); // ОК d is Derived  construct<Base>( p2, d );  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 37 (45)
  38. 38. Обмеження на зводимість  template <class Type, class Convert>  struct must_be_converted  {  ~must_be_converted()  {  void (*p)(Type &, const Convert &) =  constraints;  }  private:  static void constraints(Type & s, const Convert & t)  {  s=t; }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 38 (45)
  39. 39. Шаблон, доповнений перевіркою зведення типів  Спроба використати недопустиму  комбінацію типів діагностується компілятором  template <class T1, class T2>  void construct( T1*& p, const T2& value )  {  must_be_converted<T1, T2> check;  p =new T2(value);  return;  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 39 (45)
  40. 40. Результати третьої спроби  void converted( double*& p1, Base* p2 ) {  Base b;  Derived d;  construct( p1, 2.718 );  construct( p2, b );  construct( p1, 42 ); // ОК 42 converted to double  construct<double>( p1, 42 );   construct( p2, d ); // ОК d is Derived  construct<Base>( p2, d );  } © 2006 Бублик В.В. МООП-9. Узагальнене програмування 40 (45)
  41. 41. Перевірка примітивності типу  template <class T>  struct must_be_POD  {  ~must_be_POD()  {  void (*p)() = constraints;  }  private:  static void constraints() {  union{  T T_is_not_POD_type;};  }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 41 (45)
  42. 42. Приклади інших перевірок 42
  43. 43. Перевірка індексованості  template <class T>  struct must_be_subscriptable  {  ~must_be_subscriptable()  {  void (*p)(const T &) = constraints;  }  private:  static void constraints  (const T& T_is_not_subscriptable) {  sizeof(T_is_not_subscriptable[0]);  }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 43 (45)
  44. 44. Перевірка розмірностей  template <class T1, class T2>  struct must_have_same_size  {  ~must_have_same_size() {  void (*p)() = constraints;  }  private:  static void constraints() {  const int T1_not_same_size_as_T2 =  sizeof(T1) == sizeof(T2);  int i[T1_not_same_size_as_T2];  }  }; © 2006 Бублик В.В. МООП-9. Узагальнене програмування 44 (45)
  45. 45. Висновок  Збалансовуйте застосування успадкувань і шаблонів  Зважено контролюйте типи, але не вимагайте від них більше, ніж потрібно © 2006 Бублик В.В. МООП-9. Узагальнене програмування 45 (45)
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×