Бублик Володимир Васильович Програмування - 2 Лекція 3. Об'єктне програмування. Права доступу Лекції для студентів 2 курсу
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 2 Оголошення Для студентів другого курсу відкрито форум з об'єктно- орієнтованого програмування 1.Зайти на сторінку 2.Зареєструватися 3.Одержати електронною поштою підтвердження 4.Записатися на курс об'єктно-орієнтованого програмування 5.Спілкуватися
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 3 Звідки що видно? class Date { public: Date ( int d =0, int m=0, int y=0); Date (string USdate); // yyyy/mm/dd Date (const Date&); ~Date(); private: int _day, _month, _year; void fillDate (int d, int m, int y); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 4 Звідки що видно? class Date { public://Відкрита частина видна усім Date ( int d =0, int m=0, int y=0); Date (string USdate); // yyyy/mm/dd Date (const Date&); ~Date(); private://Закрита частина, недоступна зовні int _day, _month, _year; void fillDate (int d, int m, int y); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 5 Для чого закрита частина в заголовному файлі? #include Date.h int main() { Date today(22,1,2007); //Як виділити память під today, не знаючи //типів кожного з атрибутів? cout
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 6 Закриті атрибути Закриті атрибути, розміщені в заголовному файлі, видимі всім, хто має доступ до заголовного файлу Закриті атрибути доступні для використання лише членам класу, а також функціям або класам, яким надані для цього спеціальні повноваження (friends) Закриті атрибути можна зробити невидимими, якщо перейти до указників (ідіома pimple pointer to implementation)
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 7 Для чого закривають атрибути? Уявімо собі, що атрибути public: int _day, _month, _year; стануть відкритими.
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 8 Доступні для неконтрольованого спотворення Date myDay(18, 2, 2006); Якщо атрибути відкриті, то зміну їх значень користувачем, яка може привести до некоректності, важко контролювати myDay._day = 32; myDay._month = 13; myDay._year = 3333;
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 9 Доступ за допомогою модифікатора Модифікатор локалізує місця можливих змін значень атрибутів та контролює їх коректність void Date::setDay (int day) { fillDate(day, Month(_month), _year); return; } якщо атрибут некоректний, функція fillDate створить аварійну ситуацію,
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 10 Для чого закривають методи? Закривають службові методи, не призначені для вживання за межами класу bool Date::leapYear (int y) { bool leap; if (y % 4) leap=false; else if (y % 100) leap=true; else if (y % 400) leap=false; else leap=true; return leap; }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 11 Приклади використання закритого методу Різні види конструкторів забезпечують інтерфейс до одного і того ж методу Date::Date ( int d, Month m, int y) { fillDate(d, m, y); } Date::Date ( int d, int m, int y) { fillDate(d, Month(m), y); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 12 Атрибути об'єкту Атрибути об'єкту, як і методи _day, _month, _year позбавлені сенсу поза об'єктом Метод, наприклад, fillDate; setDay(5); month(); не можна викликати без об'єкту. Метод завжди знає свій об'єкт, до якого його застосовано. Він звертається до свого об'єкту неявно (_day, _month, _year ) або через указник this (this->_day, this->fillDate(d, m, y); )
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 13 Статичні атрибути і методи Статичний атрибут не належить жодному об'єкту Статичний метод не застосовується до жодного окремого об'єкту (він не знає this) class Date { public: static void setDefault (); //за таймером private: static Date defaultDate; static bool defaultSet; }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 14 Визначення статичного об'єкту Виклик конструктора Date Date::defaultDate;// = Date(); bool Date::defaultSet = false; void Date::fillDate(int d, Month m, int y) { if (!defaultSet) { defaultSet =true; setDefault(); } ……………………………………………
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 15 #include void Date::setDefault () { struct tm * today =new tm; time_t timer; time( &timer ); today = gmtime(&timer); defaultDate._day = today->tm_mday; defaultDate._month = ++(today->tm_mon); defaultDate._year = today->tm_year+=1900; }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 16 Обробка параметрів у конструкторі Відсутні параметри дати тепер беруться з defaultDate _day = d? d: defaultDate._day; _month=m? m: defaultDate._month; _year= y? y: defaultDate._year;
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 17 Статичні методи vs. утиліти класу Статичний метод, наприклад, Point::amount має доступ до закритої частини класу і викликається поза класом через оператор розв'язання області дії Point :: amount(); Утиліта класу, наприклад, ostream& operator
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 18 Порушення прав доступу Виняткові права доступу до атрибутів Виняткові права доступу до закритих методів Виняткові права на створення і видалення об'єктів Виняткові права можна надати Всьому класу Окремому методу Позакласній функції Для надання виняткових прав потрібні серйозні підстави
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 19 Приклад. Офіс
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 20 Винятки Тільки працедавець Employer має право створити робоче місце Employee і призначити особу Person на певну посаду Position Тільки бухгалтеру Accountant, а точніше його методу нарахування зарплати payroll() працедавець Employer надає доступ до свого штатного розпису Тільки бухгалтеру Accountant, а точніше його методу нарахування зарплати payroll (const Employee &) доступна інформація про заробітну плату посади, яку займає службовець
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 21 Службовець class Employee { friend class Employer; private: const Person & _who; const Position & _what; Employee(const Person & who, const Position & what); ~Employee(); public: const Person& who() const; const Position& what() const; };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 22 Працедавець.1 class Employer { friend void Accounter::payroll(); private: Accounter * _accounter; int _volume; struct Staff;//Hidden implementation Staff * _office;// *** pimpl
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 23 Працедавець.2 public: Employer(int volume); ~Employer(); void hire (const Person &, const Position &); void fire(int); void pay(); };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 24 Посада.1 class Position { friend void Accounter::payroll(const Employee&); private: const int _len; string _name; int _salary; int getSalary() const;
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 25 Посада.2 public: string getPositionName() const; Position(int, char [], int); ~Position(); };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 26 Особа class Person { private: const int _len; string _name; public: string getName() const; Person(int, char []); ~Person(); };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 27 Бухгалтер class Accountant { private: void payroll (const Employee &); const Employer & _myEmployer; public: Accountant (Employer & employer): _myEmployer(employer){}; ~Accountant () void payroll(); };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 28 Висновки Для порушення прав доступу повинні бути серйозні підстави, що випливають з умови задачі Статус утиліти класу ще не дає виняткових прав const Point operator+ (const Point & u, const Point & v) { return Point ( u.x()+v.x(), u.y()+v.y() ); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 29 Груба помилка class Point { friend Point operator+(const Point &, const Point &) double _x; double _y; public: Point (double x=0, double y=0); Point (const Point &); ~Point(); };
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 30 Невиправдане порушення прав доступу Прямий доступ до атрибутів нічого корисного не дає Point operator+ (const Point & u, const Point & v) { return Point ( u._x+v._x, u._y+v._y ); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 31 Утиліта vs. метод Утиліта це функція, що обслуговує клас, але не належить до класу Метод це функція-член класу, можливо, статичний Конструктори, деструктор, присвоєння не можуть бути утилітами, вони обов'язково повинні належати класу Багато функцій допускають визначення як утилітою, так і методом
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 32 Утиліти bool operator==(const Point & u, const Point & v) { return ( u.x() == v.x() ) && (u.y() == v.y() ); } const Point operator+ (const Point & u, const Point & v) { return Point ( u.x()+v.x(), u.y()+v.y() ); } Утиліта не знає this
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 33 Методи bool Point ::operator==(const Point & u) const { return ( _x == u._x ) && ( _y == u._y ); } const Point Point :: operator+ (const Point & v) const { return Point ( _x+v._x, _y+v._y ); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 34 Методи (технологічне рішення) bool Point ::operator==(const Point & u) const { return ( x() == u.x() ) && ( y() == u.y() ); } const Point Point :: operator+ (const Point & v) const { return Point ( x()+v.x(), y()+v.y() ); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 35 Методи (без скорочень) bool Point ::operator==(const Point & u) const { return ( this->x() == u.x() ) && (this-> y() == u.y() ); } const Point Point :: operator+ (const Point & v) const { return Point (this-> x()+v.x(), this-> y()+v.y() ); }
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 36 Позначення Замість u.operator==(v), як і раніше пишемо u == v; (до u добираємося через this) Нагадування. У випадку утиліти u == v; позначає operator==(u, v);
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 37 Вправа. Облік точок class InventList { friend class Point; private: InventList(); ………………………… }; Див. Lab3
© Бублик В.В. Програмування-2. Об'єктне програмування. Права доступу 38 Висновок Завжди ведіть облік об'єктам, слідкуйте за їх створенням, копіюванням і видаленням Поділ класу на методи і утиліти є важливою проблемою проектування класів Не можна доповнити чужий клас методом, а лише утилітою