Бублик Володимир Васильович Об'єктно-орієнтоване програмування Частина 1. Об'єктне програмування. Лекція 3. Права доступу Лекції для студентів 2 курсу Venezia Palazzo Ducale
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу2 Звідки що видно? 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); }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу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); }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу4 Для чого закрита частина в заголовному файлі? #include Date.h int main() { Date today(22,1,2007); //Як виділити память під today, не знаючи //типів кожного з атрибутів? cout<<today<<endl; return 0; }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу5 Закриті атрибути Закриті атрибути, розміщені в заголовному файлі, видимі всім, хто має доступ до заголовного файлу Закриті атрибути доступні для використання лише членам класу, а також функціям або класам, яким надані для цього спеціальні повноваження (friends) Закриті атрибути можна зробити невидимими, якщо перейти до указників (ідіома pimple pointer to implementation)
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу6 Для чого закривають атрибути? Уявімо собі, що атрибути public: int _day, _month, _year; стануть відкритими.
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу7 Доступні для неконтрольованого спотворення Date myDay(18, 2, 2006); Якщо атрибути відкриті, то зміну їх значень користувачем, яка може привести до некоректності, важко контролювати myDay._day = 32; myDay._month = 13; myDay._year = 3333;
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу8 Доступ за допомогою модифікатора Модифікатор локалізує місця можливих змін значень атрибутів та контролює їх коректність void Date::setDay (int day) { fillDate(day, Month(_month), _year); return; } якщо атрибут некоректний, функція fillDate створить аварійну ситуацію,
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу9 Для чого закривають методи? Закривають службові методи, не призначені для вживання за межами класу 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; }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу10 Приклади використання закритого методу Різні види конструкторів забезпечують інтерфейс до одного і того ж методу 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); }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу11 Атрибути об'єкту Атрибути об'єкту, як і методи _day, _month, _year позбавлені сенсу поза об'єктом Метод, наприклад, fillDate; setDay(5); month(); не можна викликати без об'єкту. Метод завжди знає свій об'єкт, до якого його застосовано. Він звертається до свого об'єкту неявно (_day, _month, _year ) або через указник this (this->_day, this->fillDate(d, m, y); )
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу12 Статичні атрибути і методи Статичний атрибут не належить жодному об'єкту Статичний метод не застосовується до жодного окремого об'єкту (він не знає this) class Date { public: static void setDefault (); //за таймером private: static Date defaultDate; static bool defaultSet; }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу13 Визначення статичного об'єкту Виклик конструктора Date Date::defaultDate;// = Date(); bool Date::defaultSet = false; void Date::fillDate(int d, Month m, int y) { if (!defaultSet) { defaultSet =true; setDefault(); } ……………………………………………
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу14 Часова діаграма
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу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; }
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу16 Обробка параметрів у конструкторі Відсутні параметри дати тепер беруться з defaultDate _day = d? d: defaultDate._day; _month=m? m: defaultDate._month; _year= y? y: defaultDate._year;
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу17 Статичні методи vs. утиліти класу Статичний метод, наприклад, Point::amount має доступ до закритої частини класу і викликається поза класом через оператор розв'язання області дії Point :: amount(); Утиліта класу, наприклад, ostream& operator<<(ostream&, const Point&); не має доступу до закритої частини класу і не потребує оператора розв'язання області дії
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу18 Порушення прав доступу Виняткові права доступу до атрибутів Виняткові права доступу до закритих методів Виняткові права на створення і видалення об'єктів Виняткові права можна надати Всьому класу Окремому методу Позакласній функції Для надання виняткових прав потрібні серйозні підстави
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу19 Приклад. Офіс
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу20 Винятки Тільки працедавець Employer має право створити робоче місце Employee і призначити особу Person на певну посаду Position Тільки бухгалтеру Accountant, а точніше його методу нарахування зарплати payroll() працедавець Employer надає доступ до свого штатного розпису Тільки бухгалтеру Accountant, а точніше його методу нарахування зарплати payroll (const Employee &) доступна інформація про заробітну плату посади, яку займає службовець
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу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; };
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу22 Працедавець.1 class Employer { friend void Accounter::payroll(); private: Accounter * _accounter; int _volume; struct Staff;//Hidden implementation Staff * _office;// *** pimpl
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу23 Працедавець.2 public: Employer(int volume); ~Employer(); void hire (const Person &, const Position &); void fire(int); void pay(); };
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу24 Посада.1 class Position { friend void Accounter::payroll(const Employee&); private: const int _len; string _name; int _salary; int getSalary() const;
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу25 Посада.2 public: string getPositionName() const; Position(int, char [], int); ~Position(); };
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу26 Особа class Person { private: const int _len; string _name; public: string getName() const; Person(int, char []); ~Person(); };
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу27 Бухгалтер class Accountant { private: void payroll (const Employee &); const Employer & _myEmployer; public: Accountant (Employer & employer): _myEmployer(employer){}; ~Accountant () void payroll(); };
© Бублик В.В. ООП-1. Об'єктне програмування. Права доступу28 Висновки Для порушення прав доступу повинні бути серйозні підстави, що випливають з умови задачі Статус утиліти класу, наприклад, ще не дає виняткових прав Як можна скорочуйте кількість функцій, що мають доступ до закритої частини класу, віддаючи перевагу селекторам або модифікаторам