'

МЕТОДИ ОБ'ЄКТНО-ОРІЄНТОВАНОГО ПРОГРАМУВАННЯ - 2007

Понравилась презентация – покажи это...





Слайд 0

МЕТОДИ ОБ'ЄКТНО-ОРІЄНТОВАНОГО ПРОГРАМУВАННЯ - 2007 Бублик В.В. Кафедра мультимедійних систем, кімн. 204/1 Консультації: вівторок, середа 15-16 год. http://emerecu.ukma.kiev.ua/efolio You are welcome! Stockholm, Kungliga Tekniska Hogskolan


Слайд 1

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


Слайд 2

Динамічний поліморфізм Чи завжди він потрібен?


Слайд 3

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 4 (45) Динамічний поліморфізм Пізнє зв'язування віртуальних функцій вимагає Ієрархії класів Дотримання дисципліни стабільного інтерфейсу нетермінальних класів Накладних витрат непрямого виклику


Слайд 4

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 5 (45) Поліморфна ієрархія класів Базовий клас class Base { public: virtual void vf() { cout<<"Base::f()"<<endl; } void g() { cout<<"Base::g()"<<endl; } };


Слайд 5

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 6 (45) Поліморфна ієрархія класів Похідний клас class Derived: public Base { public: virtual void vf() { cout<<" Derived ::f()"<<endl; } };


Слайд 6

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 7 (45) Заміщення при пізньому зв'язуванні void manipulator(Base & x){ x.f(); x.g(); } Base b; Derived d; manipulator(b); //Base::f();Base::g() manipulator(d); //Derived:: f();Base::g()


Слайд 7

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 8 (45) Накладні витрати поліморфізму 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


Слайд 8

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 9 (45) Внесення стабільного інтерфейсу Базовий клас class NVIBase { public: void vf() { dovf(); return;} void g() { cout<<"Base::g()"<<endl; } private: virtual void dovf() { cout<<"Base::f()"<<endl; } };


Слайд 9

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 10 (45) Внесення стабільного інтерфейсу Похідний клас class NVIDerived: public NVIBase { private: virtual void dovf() { cout<<" Derived ::f()"<<endl; } };


Слайд 10

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 11 (45) Накладні витрати невіртуального інтерфейсу Без особливих додаткових накладних витрат: один зайвий виклик невіртуальної інтерфейсної функції x.vf(); 00416E5E mov ecx,dword ptr [x] 00416E61 call NVIBase::vf (415EFBh)


Слайд 11

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 12 (45) Виділення абстрактного нетермінального класу Базовий клас class NVINTBase { public: void vf() { dovf(); return;} void g() { cout<<"Base::g()"<<endl; } virtual ~NVINTBase()=0; private: virtual void dovf() { cout<<"Base::f()"<<endl; } };


Слайд 12

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 13 (45) Виділення абстрактного нетермінального класу Похідні класи class NVITBase: public NVINTBase {}; class NVITDerived: public NVINTBase { private: virtual void dovf() { cout<<" Derived ::f()"<<endl; } };


Слайд 13

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 14 (45) Порівняння викликів деструкторів Виклик невіртуального деструктора 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


Слайд 14

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 15 (45) Порівняння викликів деструкторів Накладні витрати віртуального деструктора 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


Слайд 15

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 16 (45) Висновок Повна гнучкість рішень за рахунок динамічного розпізнавання типу об'єкту при значних затратах як на етапі програмування, так і виконання


Слайд 16

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 17 (45) “Невіртуальна” ієрархія class Base { public: void f() {cout<<"Base::f()"<<endl; } void g() {cout<<"Base::g()"<<endl; } }; class Derived : public Base { public: void f() {cout<<" Derived::f()"<<endl; } // пряме відсилання до базового класу void g() {Base::g();} };


Слайд 17

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 18 (45) Раннє зв'язування void manipulator(Base & x){ x.f(); x.g(); } Base b; Derived d; manipulator(b); //Base::f();Base::g() manipulator(d); // Base::f();Base::g()


Слайд 18

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 19 (45) Висновок Раннє зв'язування не забезпечує заміщень: при підстановці параметром об'єкту похідного класу викликаються функції базового


Слайд 19

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 20 (45) Узагальнений маніпулятор ієрархією класів 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()


Слайд 20

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 21 (45) Висновок Шаблон, застосований до ієрархії, доповненої явним делегуванням, моделює статичний поліморфізм


Слайд 21

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 22 (45) “На городі бузина...” class ElderBerry // бузина { public: void f(char a='!', double x=1, bool t=true) { cout<<"ElderBerry::f()"<<endl; } void g(char a='?') { cout<<"ElderBerry::g()"<<endl; } void goToUncle(); // у Києві };


Слайд 22

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 23 (45) А де Murgatroyd? class Murgatroyd { public: void f() { cout<<"Murgatroyd::f()"<<endl; } void g(ElderBerry & ga=ElderBerry(), double a=3.14) { cout<<" ElderBerry::g()"<<endl; ga.g(); } // An exclamation of surprise int heavensTo(const Murgatroyd &); };


Слайд 23

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 24 (45) Узагальнена функція 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()


Слайд 24

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 25 (45) Поліморфізм без ієрархії Методи узагальненого програмування дозволяють промоделювати статичний поліморфізм не застосовуючи ієрархії класів, а лише їх знайомств за умови узгодженості їх поведінки


Слайд 25

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 26 (45) Висновок Кожен початківець хоче продемонструвати володіння успадкуванням (90% випадків) Віртуальні функції найчастіше вживаються некоректно Застосовувати динамічний поліморфізм варто лише тоді, коли статичного не вистачає Узагальнене програмування найпотужніший механізм статичного поліморфізму, але...


Слайд 26

Безпечність узагальненого програмування Наперед невідомо, який саме тип буде підставлено до шаблону: як гарантувати працездатність за мінімальних вимог до типового параметру? Як уникнути збоїв на етапі виконання?


Слайд 27

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 28 (45) Синтаксичний контроль типів Успадкування типів Зведення типів Примітивність типів Індексованість типів


Слайд 28

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 29 (45) Типізація (за Бучем) Засіб захисту від використання об’єктів одного класу замість іншого, або принаймні спосіб управління цим використанням.


Слайд 29

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 30 (45) Шаблон з одним параметром Пробуємо розмістити значення Того ж типу Т на новому місці template <class T> void construct( T*& p, const T& value ) { p =new T(value); return; }


Слайд 30

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 31 (45) Застосування шаблону 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 ); }


Слайд 31

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 32 (45) Результати першої спроби 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 ); }


Слайд 32

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 33 (45) Висновок (з першої спроби) Надто жорстка умова на типовий параметр


Слайд 33

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 34 (45) Шаблон з двома параметрами Пробуємо розмістити значення типу Т2 на новому місці за указником типу Т1 Як уникнути недопустимих комбінацій типів template <class T1, class T2> void construct( T1*& p, const T2& value ) { p =new T2(value); return; }


Слайд 34

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 35 (45) Обмеження на успадкування 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; } };


Слайд 35

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 36 (45) Шаблон, доповнений перевіркою підтипів Спроба використати недопустиму комбінацію типів діагностується компілятором template <class T1, class T2> void construct( T1*& p, const T2& value ) { must_have_base<T1, T2> check; p =new T2(value); return; }


Слайд 36

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 37 (45) Результати другої спроби 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 ); }


Слайд 37

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 38 (45) Обмеження на зводимість 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; } };


Слайд 38

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 39 (45) Шаблон, доповнений перевіркою зведення типів Спроба використати недопустиму комбінацію типів діагностується компілятором template <class T1, class T2> void construct( T1*& p, const T2& value ) { must_be_converted<T1, T2> check; p =new T2(value); return; }


Слайд 39

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 40 (45) Результати третьої спроби 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 ); }


Слайд 40

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 41 (45) Перевірка примітивності типу template <class T> struct must_be_POD { ~must_be_POD() { void (*p)() = constraints; } private: static void constraints() { union{ T T_is_not_POD_type;}; } };


Слайд 41

Приклади інших перевірок


Слайд 42

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 43 (45) Перевірка індексованості 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]); } };


Слайд 43

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 44 (45) Перевірка розмірностей 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]; } };


Слайд 44

© 2006 Бублик В.В. МООП-9. Узагальнене програмування 45 (45) Висновок Збалансовуйте застосування успадкувань і шаблонів Зважено контролюйте типи, але не вимагайте від них більше, ніж потрібно


×

HTML:





Ссылка: