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

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



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

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

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

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 2 Повторення Що має бути в класі class T { private: //Тут розміщують атрибути public: //Конструктори T(T1,…,Tn); //Деструктор ~T();//далі селектори, модифікатори, … };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 3 Приклад класу. String class String { private: size_t _len; char* _allocator; public: String(); String(const char*); String(const char); ~String(); size_t length() const {return _len;} bool empty() const {return _len==0;} void clear() {*this=String();} };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 4 Констуктори Для чого у класі три різних конструктори? class String { private: size_t _len; char* _allocator; public: String(); String(const char*); String(const char); …………………………………………… };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 5 Властивість інкапсуляції Відокремлення реалізації класу від його визначення String::String (const char c): _allocator( new char [2]), _len(1) { _allocator [0]=c; _allocator [1]='\0'; return; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 6 Питання Чому у визначенні класу розміщені реалізації? class String { private: size_t _len; char* _allocator; public:………………………………………….. size_t length() const {return _len;} bool empty() const {return _len==0;} void clear() {*this=String();} };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 7 Питання Чи коректний параметр замовчування? Ні. Чому? class String { private: size_t _len; char* _allocator; public: String (); String (const char* ps=0); String (const char); ~String (); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 8 Конструктор копіювання class T { T(T1,…,Tn); ~T(); //конструктор копіювання //створює новий об'єкт, ідентичний //переданому параметром T(const T&); //Можливий варіант: T(T&); //але не Т(Т) };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 9 Використання Конструктор копіювання викликається кожного разу, коли параметр або результат передаються значеннями T1 f(T2 x) { T1 y; // тіло f… return y; } a=f(b);//T2 x(b); T1 y; тіло f… ; a = T1(y);

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 10 Інвентаризація об'єктів class Point { static int _freeID; const int _pointID; double _x; double _y; public: Point (double x=0, double y=0); Point (const Point &); ~Point(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 11 Конструктор Point Point::Point (double x, double y): _x (x), _y (y), pointID (++_freeID) { #ifdef NDEBUG cout<<pointID<<": created "<<*this<<endl; #endif return; }; //Де коректно розмістити замовчування параметру?

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 12 Копіювальний конструктор Point Point::Point (const Point & u): _x (u._x), _y (u._y), pointID(++_freeID) { #ifdef NDEBUG cout<<pointID<<": copied "<<*this<<endl; #endif return; }; //Чи може копіювання мати замовчуваний параметр?

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 13 Деструктор Point Point::~Point() { #ifdef NDEBUG cout<<pointID<<": removed "<<*this<<endl; #endif return; };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 14 Передача об'єктів параметрами Значенням Point operator+ (Point u, Point v) { Point res(u.x()+v.x(), u.y()+v.y()); return res; } Відсилками ostream& operator<<(ostream &os, const Point& u) { os<<'('<<u.x()<<','<<u.y()<<')'; return os; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 15 Протокол int main() { Point a(1,2); Point b(5); a+b; return 0; } 1: created (1,2)//a 2: created (5,0)//b 3: copied (5,0)//v 4: copied (1,2)//u 5: created (6,2)//res 6: copied (6,2)//return 5: removed (6,2)//res 4: removed (1,2)//u 3: removed (5,0)//v 6: removed (6,2)//returned 2: removed (5,0)//b 1: removed (1,2)//a

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 16 Вправа до передачі об'єктів параметрами Що зміниться в протоколі, якщо у виводі забрати сталу відсилку? ostream& operator<<(ostream &os, Point u) { os<<'('<<u.x()<<','<<u.y()<<')'; return os; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 17 Без локальної змінної Point operator+ (Point u, Point v) { /*Замість Point res(u.x()+v.x(), u.y()+v.y()); return res; */ return Point ( u.x()+v.x(), u.y()+v.y() ); }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 18 Протокол 2 int main() { Point a(1,2); Point b(5); a+b; return 0; } 1: created (1,2)//a 2: created (5,0)//b 3: copied (5,0)//v 4: copied (1,2)//u 5: created (6,2)//return 4: removed (1,2)//u 3: removed (5,0)//v 5: removed (6,2)//returned 2: removed (5,0)//b 1: removed (1,2)//a

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 19 Сталі відсилки Point operator+ (const Point & u, const Point & v) { return Point ( u.x()+v.x(), u.y()+v.y() ); }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 20 Протокол 3 int main() { Point a(1,2); Point b(1); a+b; return 0; } 1: created (1,2)//a 2: created (5,0)//b 3: created (6,2)//return 3: removed (6,2)//returned 2: removed (5,0)//b 1: removed (1,2)//a

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 21 Урок передачі параметрів Передаючи параметр і одержуючи результат, усвідомлюйте, з чим маєте справу: з оригіналом чи копією

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 22 Копіювання агрегатів class WrappedVector { private: static const size_t n; double * v; public: WrappedVector(); WrappedVector(const WrappedVector&); ~WrappedVector(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 23 Копіювальний конструктор вектора WrappedVector:: WrappedVector (const WrappedVector& vec): _v (new double[_n]) { for (size_t i=0; i<_n; i++) _v[i] = vec._v[i]; return; } //Як бути з нестачею пам'яті?

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 24 Копіювальний конструктор за замовчуванням WrappedVector:: WrappedVector (const WrappedVector& vec): _v (vec._v) { }; //Чим закінчиться виконання програми? int main() { WrappedVector u, v(u); return 64; //катастрофою!!! }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 25 Копіювання присвоєнням class WrappedVector { private: static const size_t n; double * v; public: WrappedVector(); WrappedVector(const WrappedVector&); ~WrappedVector(); WrappedVector& operator= (const WrappedVector&); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 26 Реалізація копіювального присвоєння WrappedVector& WrappedVector::operator= (const WrappedVector& vec) { //Нам поталанило: vec і this мають одну й ту ж довжину for (size_t i=0; i<n; i++) v[i] = vec.v[i]; return *this; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 27 Присвоєння за замовчуванням WrappedVector& WrappedVector :: operator= (const WrappedVector& vec) { v = vec; return *this; } //Чим закінчиться виконання програми? int main() { WrappedVector u, v; u=v; return 64;//знову катастрофою!!! }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 28 Вектори різної довжини class DissimilarVector { private: size_t _n;//non static, non const(?) double * _v; public: DissimilarVector(int); DissimilarVector(const DissimilarVector&); ~DissimilarVector(); DissimilarVector& operator=(const DissimilarVector&); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 29 Конструктор вектора DissimilarVector:: DissimilarVector (size_t len) : _n (len), _v (new double[n]) { for (size_t i=0; i<_n; i++) _v[i] = 0; return; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 30 Копіювальний конструктор DissimilarVector:: DissimilarVector (const DissimilarVector& vec): _n (vec._n), _v (new double[vec._n]) { if (_v==0) //throw exeption for (size_t i=0; i<_n; i++) _v[i] = vec._v[i]; return; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 31 Чому атрибут _n не може бути сталим? 1.Спробуйте присвоєння за замовчуванням 2.Навіть копіювальне присвоєння, взагалі кажучи, не працюватиме

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 32 Копіювальне присвоєння DissimilarVector& DissimilarVector::operator= (const DissimilarVector& vec) { //1. Видалити старий об'єкт if (this==&vec) return *this; delete [] _v; //2. Створити новий об'єкт _n = vec._n; _v = new double[_n]; //3. Скопіювати значення for (size_t i=0; i<_n; i++) _v[i] = vec._v[i]; return *this; } _n = vec._n

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 33 Рядки з копіюванням class String { private: size_t _len; char* _allocator; public: String(); String(const char*); String(const char); String (const String & s); ~String(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 34 Копіювальний конструктор рядка String::String(String& s): _len( s._len), _allocator( new char[_len+1]) { strcpy(_allocator, s._allocator); return; };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 35 Редагування оригіналу (без const) class String { private: size_t _len; char* _allocator; int _amountOfCopies; public: String(); String(const char*); String(const char); String (String & s); ~String(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 36 Копіювання з редагуванням String::String(String& s): _len( s._len), _allocator( new char[_len+1]) { //Кількість копій, зроблених з оригіналу //збільшується на одиницю s._amountOfCopies++; strcpy(_allocator, s._allocator); return; };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 37 Мультиконструктор копіювання class String { public: String(); String(const char*); String(const char); String(const String & s, int multiplayer=1); ~String(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 38 Реалізація мультиконструктора копіювання String:: String(const String & s, int multiplayer): _len (s._len*multiplayer), _allocator (new char [_len+1]) { char * target = _allocator; for (int i=0; i<multiplayer; i++) { strcpy(target, s._allocator); target+=s._len; } return; };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 39 Застосування копіювання char * p …..; // Common constructor String s(p); // Copy version of multiplication constructor String ss(s); // Multiplication constructor String s10(s,10);

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 40 Проблема замовчуваного параметру Що станеться, якщо замовчуваний параметр перенести до реалізації? Катастофа class String { public: String(const String & s, int multiplayer); }; String:: String(const String & s, int multiplayer=1):…{…;} Чому?

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 41 Некоректне копіювання #include String.h // Common constructor String s(p); // Default copy constructor String ss(s); // Multiplication constructor String s10(s,10);

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 42 Сигнатури присвоєнь Якій з сигнатур віддати перевагу? 1.void operator=( T&); 2.T operator=( T&); 3.T& operator=( T ); 4.T operator=( T ); 5.T& operator=( T&);

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 43 Сигнатури присвоєнь Якій з сигнатур віддати перевагу? 1.void operator=( T&);//Як бути з x=y=z; 2.T operator=( T&);//чим копіювати результат? 3.T& operator=( T );//чим копіювати параметр? 4.T operator=( T );//див 2 і 3 разом 5.T& operator=( T&);//ОК!!!

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 44 Сигнатури присвоєнь Якій з сигнатур віддати перевагу? 1.void operator=( T&); 2.T operator=( T&); 3.T& operator=( T ); 4.T operator=( T ); 5.T& operator=( T&); T& operator=(const T&);

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 45 Що таке this? class T { public: T(T1,…,Tn); ~T(); T(const T&); T& operator= (const T&); }; this має тип T * const

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 46 Чому * const? this не можна перемістити на інший об'єкт this = anything; не коректно

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 47 Повернення значення в присвоєнні Point& Point::operator=(const Point & u) { this ->_x = u._x; *this._y = u._y; return *this; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 48 Рядки з присвоєнням class String { public: String(); String(const char*); String(const char); String(const String & s, int multiplayer=1); String& operator=(const String&); ~String(); };

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 49 Присвоєння рядків String& String::operator=(const String& s) { if (this==&s) return *this; delete [] _allocator; _len = s._len; _allocator = new char[_len+1]; strcpy(_allocator, s._allocator); return *this; }

© Бублик В.В. ООП-1. Об'єктне програмування. Копіювання об'єктів 50 Висновки Конструктор копіювання створює новий об'єкт Присвоєння звичайно замінює існуючий об'єкт іншим об'єктом (навіть якщо не доводиться видаляти попередні значення) Присвоєння не можна визначити поза класом Присвоєння в класі T має тип T& (чому?) Присвоєння повертає *this, конструктори не повертають нічого (чому?)