Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 6. Типізація членів класу Лекції для студентів.

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



Advertisements
Похожие презентации
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 2. Копіювання об'єктів Лекції для студентів 2.
Advertisements

Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 7. Контейнерні класи Лекції для студентів 2 курсу.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 3. Права доступу Лекції для студентів 2 курсу.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 5. Програмовані операції Лекції для студентів.
Вказівники Вказівник (або покажчик) – особливий тип даних, значенням якого є адреса певного байта оперативної памяті. Значення покажчика - це беззнакове.
Бублик Володимир Васильович Процедурне програмування C/C++ Лекція 10. Статичний поліморфізм Лекції для студентів 2 курсу Консультації: середа год.,
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 1. Принцип інкапсуляції Лекції для студентів 2.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 2. Ієрархічне програмування. Лекція 9. Відкрите успадкування Лекції для студентів.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 8. Параметризовані класи Лекції для студентів.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 2. Ієрархічне програмування. Лекція 10. Успадкування реалізації (закрите і захищене)
Верона (Італія). Арена, І ст. Якби будівельники будували будинки так, як програмісти складають програми, досить було б залетіти одному дятлу, щоб зруйнувати.
Опрацювання структур у функціях Оскільки мова С інтерпретує структури як звичайні змінні, а не вказівники, можна передавати значення структури у функцію.
Бублик Володимир Васильович Об'єктно- орієнтоване програмування Частина 2. Ієрархічне програмування. Лекція 12. Ітераторні контейнери Лекції для студентів.
Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 4. Ієрархія обєктів: композиція і агрегація Лекції.
Класи пам'яті даних. Клас пам'яті, час існування та видимість об'єкта Кожен обєкт програми (змінна, функція,...) має свій тип і клас памяті. Тип визначає.
Бублик Володимир Васильович Об'єктно- орієнтоване програмування Частина 2. Ієрархічне програмування. Лекція 11. Поліморфізм Лекції для студентів 2 курсу.
Бублик Володимир Васильович Програмування - 2 Лекція 3. Об'єктне програмування. Права доступу Лекції для студентів 2 курсу.
Бублик Володимир Васильович Процедурне програмування C/C++ Лекція 7. Базові поняття програмування. Структури даних Лекції для студентів 2 курсу Консультації:
Вказівники на функції В мові С імя функції є константним вказівником на перший байт виконавчого коду функції. Це адреса оперативної памяті, яка відповідає.
Оператори. Введення і виведення даних. Оператор присвоювання Оператори це команди програми. Оператор присвоювання є основним оператором мови програмування.
Транксрипт:

Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 6. Типізація членів класу Лекції для студентів 2 курсу Odeon Square München, Odeonsplatz

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 2 Повторення Тип функції (оператора) визначається її (його) сигнатурою Приклад. Альтернативні сигнатури додавання комплексних чисел 1.const Complex operator+ (const Complex &, const Complex &); 2.const Complex operator+(const Complex, const Complex); 3.const Complex operator+(Complex, Complex); Помилкова сигнатура: Complex operator+(Complex, Complex); Чому? Complex(1,1)+Complex(3,2) = Complex(-1,-1); Complex(1,1)+Complex(3,2) = 0; (Complex(1,1)+Complex(3,2)).re()=0;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 3 Повторення: указники функцій Інтегрування за Сімпсоном: сигнатура дозволяє правильно підібрати підхожі функції double Simpson (double a, double b, double eps, double (*f) (double)); double exp2(double x) { return exp (-x*x); } double (*p_exp) (double) = exp2; Simpson(0, 1, 1e-10, p_exp); double (* const const_p_exp) (double) = exp2; Simpson(0, 1, 1e-10, const_p_exp);

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 4 Указники операцій (нічого нового) //Визначення указника операції const Complex (* ptr_to_op ) (const Complex &, const Complex &) = operator+; //Визначення сталого указника операції const Complex (* const const_ptr_to_op ) (const Complex &, const Complex &) = operator+;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 5 Типи указників //Тип указника PFR //(Pointer to Function with Referenced parameters) typedef const Complex (*PFR) (const Complex &, const Complex &); //Тип указника CPFR //(Constant Pointer to Function …) typedef const Complex (* const CPFR) (const Complex &, const Complex &);

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 6 Визначення указників //Визначення указника типу PFR //(Pointer to Function with Referenced parameters) PFR pf = operator+; //Визначення сталого указника типу СPFR //(Constant Pointer to Function with Referenced …) CPFR addition = operator+; Питання. Для чого потрібні сталі указники функцій? Відповідь. Для правильної передачі функціональних параметрів

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 7 Комплексний калькулятор class ComplexCalc { Complex _a, _x; public: ComplexCalc (const Complex& a =0, const Complex& x=0): _a(a),_x(x){}; const Complex& getA() const {return _a; } const Complex& getX() const {return _x; } void setA (const Complex& a ) { _a = a; } void setX (const Complex& x ) { _x = x; } // Інфіксний запис типу _a op _x тут не проходить: const Complex doOper(CPFR op) {return _a=op(_a,_x);} };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 8 Застосування указників операцій ComplexCalc cc(1, Complex(0,1)); cout<<cc.getA()<<'+'<<cc.getX() <<'='<<cc.doOper(operator+)<<endl; cout<<cc.getA()<< endl; cc.setX(2); cout<<cc.getA()<<'*'<<cc.getX() <<'='<<cc.doOper(operator*)<<endl; cout<<cc.getA()<< endl;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 9 Інше застосування указників операцій ComplexCalc cc(1, Complex(0,1)); CPFR poper[] = { operator+, operator-, operator*, operator/ }; int i=0; //Майже меню cout<<Which operation to calculate?; cin>>i; cout<<cc.doOper(poper[i])<<endl;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 10 Замінимо утиліти методами //Метод додавання const Complex Complex :: operator+ (const Complex&) const; Тепер тип оператора змінився і старе визначення указника не пройде const Complex (*ptr_to_op) (const Complex &, const Complex &) = operator+; Утиліта має два параметри, а метод має один параметр, але знає свій об'єкт this іншого, ніж параметр типу

Питання перше Ми вміємо взяти довільну функцію заданої сигнатури, наприклад, double (*pf) (double); Complex (*op)(const Complex&, const Complex&); Complex (*const op)(const Complex&, const Complex&); Як сказати: Візьми довільну операцію або функцію певної сигнатури серед членів заданого класу? © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 11

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 12 Тип указника методу //Тип указника CPMFR //(Constant Pointer to member Function //with a Referenced parameter) typedef const Complex (Complex::* const CPMFR) (const Complex &) const; CPMFR cp = Complex::operator*; // Інфіксний запис тепер знову не пройде: // В обєкті z1 беремо метод, на який вказує // указник cp, і застосовуємо його до обєкту z2 cout<<(z1.*cp)(z2)<<endl;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 13 Вправа Перепишіть комплексний калькулятор для операцій, реалізованих методами класу

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 14 Приклад. Текстовий екран // Текстовий екран максимальним розміром // maxHeigh х maxWidth class Screen { public: //Екран заповнюється рядком pc, //якщо він заданий, інакше він наповнюється //наповнювачем _filler Screen(int, int, char* pc =0); ~Screen(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 15 Атрибути екрану private: //Наповнювач static const char _filler; //Фактична висота екрану int _height; //Фактична ширина екрану int _width; //Наповнення екрану char *_wContent; //Курсор mutable int _cursor;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 16 Перевести курсор в початок екрану Screen& Screen::home() { _cursor=0; return *this; }; //Сталий метод const Screen& Screen::home() const { _cursor=0; return *this; };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 17 Несуттєві атрибути Виділимо атрибути, які з точки зору розробника не впливають на стан об'єкту Якщо розробник вважає, що стан екрану виражається його наповненням, а не місцем розташування курсору, то визначимо відповідний атрибут як несуттєвий //Курсор (несуттєвий атрибут) mutable int _cursor; Несуттєві атрибути дозволяється модифікувати навіть у сталих об'єктів

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 18 Парні методи (модифікують _cursor) const Screen& home() const; Screen& home(); const Screen& move() const; Screen& move(); const Screen& move(int, int) const; Screen& move(int, int); const Screen& back() const; Screen& back(); const Screen& show(ostream&) const; Screen& show(ostream&);

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 19 Непарні методи //Очистити екран Screen& clear(); //Показати символ, на якому знаходиться курсор //непарний метод для ілюстрації проблеми const Screen& showCurrent() const; //Селектор char get() const; //Модифікатор Screen& set(char);

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 20 Для чого потрібні парні методи? Screen v(4,4," "); v.show().set('*'). // Screen& move(int, int); тому можна застосувати set move(1,1).set('*'). move(2,2).set('*'). //showCurrent(). //непарна функція, тому застосувати set не можна //const Screen& showCurrent() const; move(3,3).set('*'). show();

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 21 Сталий результат До сталого результату можна застосовувати лише сталі методи const Screen cv(5,5,"aaaaabbbbbcccccdddddeeeee"); cv.show().move(1,1).showCurrent(). move(2,2).showCurrent(). move(3,3).showCurrent(). show();

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 22 Указники екранних методів Указник довільного методу typedef Screen& (Screen::* const NonConstAction) (); Указник сталого методу typedef const Screen& (Screen::* const ConstAction) () const;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 23 Застосування указника методу // Застосувати до екрану s метод act n разів void doAction (Screen& s, Action act, int n) { for (int i=0; i<n; i++) (s.*act)(); }

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 24 Застосування указника сталого методу // Застосувати до екрану s сталий метод act n разів void doActionConst (const Screen& s, ConstAction act, int n) { for (int i=0; i<n; i++) (s.*act)(); }

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 25 Застосування: програмування меню //Меню екранних операцій const ConstAction menuConst[] = { Screen::home, Screen::move, Screen::back, Screen::show }; //Вибір операції із меню doActionConst(cv, menuConst[k], n);

Виведення екрану Стандартний прийом реалізації утиліти через метод (забігаючи наперед, досягнення поліморфних утиліт) ostream& operator<<(ostream & os, const Screen & s) { return s.show(os); } © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 26

Тестова програма. Андріївський стяг int main() { const int size=10; Screen demo (size, size); cout<<"Empty screen created"<<endl<<demo<<endl; // Заповнення основної діагоналі for(int i=0; i<=size; i++) demo.set('*').move(i, i); // Заповнення допоміжної діагоналі for(int i=0; i<=size; i++) demo.move(size-i-1, i).set('*'); cout<<"The screen filled"<<end<<demo<<endl; return 0; } © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 27

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 28 Приклад. Калькулятор // Арифметичний калькулятор struct Calc { // Регістр акумулятора double _a; // Регістр x double _x; // a= x + a double add() { return _a= _x + _a; } //Інші операції } ;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 29 Вправа Доповнити визначення простого арифметичного калькулятора. Визначити сигнатуру і реалізацію утиліти exe(), здатну виконувати довільну його операцію

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 30 Указники в об'єктах struct T {double a; double b; double c;} Доступ до заданого атрибуту за іменем довільного об'єкта T x; x.a; x.b; x.c; Доступ до заданого атрибуту за указником довільного об'єкта T * p = new T; p -> a; p->b; p->c;

Питання друге Ми можемо взяти довільний елемент у масиві, наприклад, double triple[3]; int i; ……; triple[i]; А як звернутися до довільного атрибуту підхожого атрибуту структури, наприклад, сказавши: Візьми будь- який з дійсних членів структури struct T {double a; double b; double c;} або хоча б об'єкта T x; © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 31

Штабелі регістрів struct RegisterPile { // Регістр a unsigned int _a; // Регістр b unsigned int _b; // Регістр c unsigned int _c; // Регістр d unsigned int _d; }; Як звернутися до довільного регістру? © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 32

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 33 Указник атрибуту //Указник будь-якого регістру в штабелі typedef unsigned int RegisterPile ::*Register; //Указник регістру а в довільному штабелі Register ra = & RegisterPile ::a; //Указник регістру b в довільному штабелі Register rb = & RegisterPile ::b; //Указник регістру c в довільному штабелі Register rc = & RegisterPile ::c; //Указник регістру d в довільному штабелі Register rd = & RegisterPile ::d;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 34 Тестова програма RegisterPile test = { 0x , 0xF , 0xFF010101, 0xFFFF0101 }; //регістр а зсунути на 1 sout<<cycleShiftL(ra, test, 1)<<endl; //регістр b зсунути на 4 sout<< cycleShiftL(rb, test, 4)<<endl; //регістр c зсунути на 8 sout<< cycleShiftL(rc, test, 8)<<endl; //регістр b зсунути на 16 sout<< cycleShiftL(rd, test, 16)<<endl;

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 35 Указник атрибуту параметром //Циклічний зсув довільного регістру regPtr в штабелі с unsigned int cycleShiftL ( unsigned int RegisterPile::*regPtr, RegisterPile& c, int n) { //Працюємо з переданим регістром for (int i= 0; i<n; ++i) c.*regPtr = (c.*regPtr >> 31)|(c.*regPtr<<=1); return c.*regPtr; }

Серйозніший приклад. Центр мас Система матеріальних точок © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 36

Структура матеріальної точки //Матеріальна точка struct MPoint { //Координати точки double _x, _y, _z; //Маса точки double _m; }; © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 37

Координата х центру мас //Координата х центру мас double centerx(const MPoint p[], size_t number) { double moment=0 ; double sum=0 ; for (int i=0; i<number; ++i) { moment += p[i]._m*p[i]._x; sum += p[i]._m; } return moment/sum; } І так для кожної координати © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 38

Альтернатива //Матеріальна точка struct ArrayPoint { //Координати точки double [3] _coord; //Маса точки double _m; }; double center(const ArrayPoint p[], size_t n, size_t i); © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 39

Довільна координата центру мас double center (const MPoint p[], size_t number, double MPoint::*pcoord) { double moment=0; double sum=0; for (int i=0; i<number; ++i) { moment += p[i]._m*p[i].*pcoord; sum += p[i]._m; } return moment/sum; } © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 40

Обчислення центру мас //Обчислимо і виведемо координату x cout<<center(s, n, &MPoint::_x)<<', // vs centerx(s, n); //Обчислимо і виведемо координату y <<center(s, n, &MPoint::_y)<<',' // vs centery(s, n); //Обчислимо і виведемо координату z <<center(s, n, &MPoint::_z)<<endl; // vs centerz(s, n); © Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 41

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 42 Указники статичних членів класу Практично не відрізняються від звичайних

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 43 Приклад. Банк class Bank { friend class CurrentAccount; private: const int _bankId; static double _normalInterestRate; static double _advancedInterestRate; static double _goldInterestRate; public: static void raiseInterest(CurrentAccount& account); };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 44 Приклад. Поточний рахунок class CurrentAccount { private: const int _accountNo; static const _freeAccountNo; const Date _openingDate; int _balance; const int & _bankId; const double * _interestRatePtr; void (* _raiseInterestPtr) (CurrentAccount&); };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 45 Приклад. Конструктор CurrentAccount(const Bank & bank, int initBalance): _accountNo(_freeAccountNo), _balance(initBalance), _bankId(bank.getId()), //статичний атрибут банку _interestRatePtr (&Bank::_normalInterestRate), //статичний метод банку //void (*) (CurrentAccount&); _raiseInterestPtr (&Bank::raiseInterest) { …………………………………………………. };

© Бублик В.В. ООП-1. Об'єктне програмування. Лекція 6. Типізація обєктів 46 Висновок Типи позакласних функцій і нестатичних методів класу розрізняються за рахунок наявності чи відсутності можливості використовувати поточний об'єкт Відсилаючи до статичних методів, вказуємо область імен класу Нестатичні атрибути вимагають уточнення класу в своєму типі, оскільки для доступу до них необхідно знати об'єкт Тип статичних атрибутів від класу не залежить