Бублик Володимир Васильович Програмування - 2 Лекція 2. Об'єктне програмування. Копіювання об'єктів  Лекції для студентів ...
Повторення <ul><li>Що має бути в класі </li></ul><ul><li>class  T </li></ul><ul><li>{ </li></ul><ul><li>private : </li></u...
Клас  String <ul><li>class  String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; </li></u...
Питання <ul><li>Чи коректно наступне визначення?  ― Ні. Чому? </li></ul><ul><li>class  String </li></ul><ul><li>{ </li></u...
Конструктор копіювання <ul><li>class  T </li></ul><ul><li>{ </li></ul><ul><li>T(T1,…,Tn); </li></ul><ul><li>~T(); </li></u...
Використання <ul><li>Конструктор копіювання викликається  кожного  разу, коли параметр або результат передаються значенням...
Інвентаризація об'єктів <ul><li>class  Point </li></ul><ul><li>{ </li></ul><ul><li>static int   _ freeID; </li></ul><ul><l...
Конструктор  Point <ul><li>Point::Point ( double  x,  double  y): </li></ul><ul><li>_x (x), </li></ul><ul><li>_y (y), </li...
Копіювальний конструктор  Point <ul><li>Point::Point ( const  Point & u): </li></ul><ul><li>_x (u._x), </li></ul><ul><li>_...
Деструктор  Point <ul><li>Point::~Point() </li></ul><ul><li>{ </li></ul><ul><li>cout<<pointID<<&quot;: removed &quot;<<* t...
Передача об'єктів параметрами <ul><li>Значенням </li></ul><ul><li>Point  operator + (Point u, Point v) </li></ul><ul><li>{...
Протокол <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(5); </li></ul><...
Вправа до передачі об'єктів параметрами <ul><li>Що зміниться в протоколі, якщо у виводі забрати сталу відсилку? </li></ul>...
Без локальної змінної <ul><li>Point operator+ (Point u, Point v) </li></ul><ul><li>{ </li></ul><ul><li>/* Замість </li></u...
Протокол 2 <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(5); </li></ul...
Сталі відсилки <ul><li>Point  operator + ( const  Point & u,  const  Point & v) </li></ul><ul><li>{ </li></ul><ul><li>retu...
Протокол  3 <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(1); </li></u...
Урок  передачі параметрів <ul><li>Передаючи параметр і одержуючи результат, усвідомлюйте, з чим маєте справу: з оригіналом...
Копіювання агрегатів <ul><li>class  WrappedVector </li></ul><ul><li>{ </li></ul><ul><li>private: </li></ul><ul><li>static ...
Копіювальний конструктор вектора <ul><li>WrappedVector:: </li></ul><ul><li>WrappedVector   ( const  WrappedVector& vec): <...
Копіювальний конструктор за замовчуванням <ul><li>WrappedVector:: </li></ul><ul><li>WrappedVector   ( const  WrappedVector...
Копіювання присвоєнням <ul><li>class  WrappedVector </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>stat...
Реалізація копіювального присвоєння <ul><li>WrappedVector&  WrappedVector:: operator = ( const  WrappedVector& vec) </li><...
Присвоєння за замовчуванням <ul><li>WrappedVector&  WrappedVector:: operator = ( const  WrappedVector& vec) </li></ul><ul>...
Вектори різної довжини <ul><li>class  DissimilarVector </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>i...
Конструктор вектора <ul><li>DissimilarVector:: </li></ul><ul><li>DissimilarVector   ( int   len ) :  </li></ul><ul><li>_ n...
Копіювальний конструктор <ul><li>DissimilarVector:: </li></ul><ul><li>DissimilarVector ( const  DissimilarVector& vec): </...
Чому атрибут  _ n не може бути сталим?   <ul><li>Спробуйте присвоєння за замовчуванням </li></ul><ul><li>Навіть копіювальн...
Копіювальне присвоєння <ul><li>DissimilarVector& DissimilarVector:: operator = ( const  DissimilarVector& vec) </li></ul><...
Рядки з копіюванням <ul><li>class  String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; <...
Копіювальний конструктор рядка <ul><li>String::String(String& s) </li></ul><ul><li>_len( s._len), </li></ul><ul><li>_alloc...
Редагування оригіналу (без  const) <ul><li>class  String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li...
Копіювання з редагуванням <ul><li>String::String(String& s) </li></ul><ul><li>_amountOfCopies (0), </li></ul><ul><li>_len(...
Мультиконструктор копіювання <ul><li>class  String </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>String...
Реалізація мультиконструктора копіювання <ul><li>String:: String( const  String & s,  int  multiplayer): </li></ul><ul><li...
Застосування копіювання <ul><li>// Common constructor </li></ul><ul><li>String s(p); </li></ul><ul><li>// Copy  version of...
Проблема замовчуваного параметру <ul><li>Що станеться, якщо замовчуваний параметр перенести до реалізації?  ―  Катастофа <...
Некоректне копіювання <ul><li>// Common constructor </li></ul><ul><li>String s(p); </li></ul><ul><li>//  Default  copy con...
Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void   operator =( T&) ; </li></ul><ul><li...
Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void   operator =( T&) ; </li></ul><ul><li...
Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void   operator =( T&) ; // Як бути з  x=y...
Що таке  this? <ul><li>class  T </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>T(T1,…,Tn); </li></ul><ul...
Чому  * const ?   <ul><li>this   не можна перемістити на інший об'єкт </li></ul><ul><li>this  = anything;  не коректно </l...
Повернення значення в присвоєнні <ul><li>Point&  Point:: operator =( const  Point & u) </li></ul><ul><li>{ </li></ul><ul><...
Рядки з присвоєнням <ul><li>class  String </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>String(); </li>...
Присвоєння рядків <ul><li>String& String:: operator =( const  String& s) </li></ul><ul><li>{ </li></ul><ul><li>if  ( this ...
Висновки <ul><li>Конструктор копіювання створює новий об'єкт </li></ul><ul><li>Присвоєння звичайно замінює існуючий об'єкт...
Upcoming SlideShare
Loading in...5
×

02 Copying Objects

393

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
393
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "02 Copying Objects"

  1. 1. Бублик Володимир Васильович Програмування - 2 Лекція 2. Об'єктне програмування. Копіювання об'єктів Лекції для студентів 2 курсу
  2. 2. Повторення <ul><li>Що має бути в класі </li></ul><ul><li>class T </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>// Тут розміщують атрибути </li></ul><ul><li>public : </li></ul><ul><li>// Конструктори </li></ul><ul><li>T(T1,…,Tn); </li></ul><ul><li>// Деструктор </li></ul><ul><li>~T(); // далі селектори, модифікатори, … </li></ul><ul><li>}; </li></ul>
  3. 3. Клас String <ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; </li></ul><ul><li>char * _allocator; </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char *); </li></ul><ul><li>String( const char ); </li></ul><ul><li>~String(); </li></ul><ul><li>// Чому нижче наведені методи разом з реалізаціями? </li></ul><ul><li>size_t length() const { return _len;} </li></ul><ul><li>bool empty() const { return _len==0;} </li></ul><ul><li>void clear() {* this =String();} </li></ul><ul><li>}; </li></ul>
  4. 4. Питання <ul><li>Чи коректно наступне визначення? ― Ні. Чому? </li></ul><ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; </li></ul><ul><li>char * _allocator; </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char * ps=0 ); </li></ul><ul><li>String( const char ); </li></ul><ul><li>~String(); </li></ul><ul><li>}; </li></ul>
  5. 5. Конструктор копіювання <ul><li>class T </li></ul><ul><li>{ </li></ul><ul><li>T(T1,…,Tn); </li></ul><ul><li>~T(); </li></ul><ul><li>// конструктор копіювання </li></ul><ul><li>// створює новий об'єкт, ідентичний </li></ul><ul><li>// переданому параметром </li></ul><ul><li>T( const T&); </li></ul><ul><li>// Можливий варіант: T(T&); </li></ul><ul><li>// але не Т(Т) </li></ul><ul><li>}; </li></ul>
  6. 6. Використання <ul><li>Конструктор копіювання викликається кожного разу, коли параметр або результат передаються значеннями </li></ul><ul><li>T1 f(T2 x) </li></ul><ul><li>{ </li></ul><ul><li>T1 y;… </li></ul><ul><li>return y; </li></ul><ul><li>} </li></ul><ul><li>a=f(b); // T2 x(b); … ; a = T1(y); </li></ul>
  7. 7. Інвентаризація об'єктів <ul><li>class Point </li></ul><ul><li>{ </li></ul><ul><li>static int _ freeID; </li></ul><ul><li>const int _pointID; </li></ul><ul><li>double _x; </li></ul><ul><li>double _y; </li></ul><ul><li>public: </li></ul><ul><li>Point ( double x=0, double y=0 ); </li></ul><ul><li>Point ( const Point &); </li></ul><ul><li>~Point() ; </li></ul><ul><li>}; </li></ul>
  8. 8. Конструктор Point <ul><li>Point::Point ( double x, double y): </li></ul><ul><li>_x (x), </li></ul><ul><li>_y (y), </li></ul><ul><li>pointID (++ _ freeID) </li></ul><ul><li>{ </li></ul><ul><li>cout<<pointID<<&quot;: created &quot;<<* this <<endl; </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  9. 9. Копіювальний конструктор Point <ul><li>Point::Point ( const Point & u): </li></ul><ul><li>_x (u._x), </li></ul><ul><li>_y (u._y), </li></ul><ul><li>pointID(++_freeID) </li></ul><ul><li>{ </li></ul><ul><li>cout<<pointID<<&quot;: copied &quot;<<* this <<endl; </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  10. 10. Деструктор Point <ul><li>Point::~Point() </li></ul><ul><li>{ </li></ul><ul><li>cout<<pointID<<&quot;: removed &quot;<<* this <<endl; </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  11. 11. Передача об'єктів параметрами <ul><li>Значенням </li></ul><ul><li>Point operator + (Point u, Point v) </li></ul><ul><li>{ </li></ul><ul><li>Point res(u.x()+v.x(), u.y()+v.y()); </li></ul><ul><li>return res; </li></ul><ul><li>} </li></ul><ul><li>Відсилками </li></ul><ul><li>ostream& operator <<(ostream &os, const Point& u) </li></ul><ul><li>{ </li></ul><ul><li>os<<'('<<u.x()<<','<<u.y()<<')'; </li></ul><ul><li>return os; </li></ul><ul><li>} </li></ul>
  12. 12. Протокол <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(5); </li></ul><ul><li>a+b; </li></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul><ul><li>1: created (1,2) //a </li></ul><ul><li>2: created (5,0) //b </li></ul><ul><li>3: copied (5,0) //v </li></ul><ul><li>4: copied (1,2) //u </li></ul><ul><li>5: created (6,2) //res </li></ul><ul><li>6: copied (6,2) //return </li></ul><ul><li>5: removed (6,2) //res </li></ul><ul><li>4: removed (1,2) //u </li></ul><ul><li>3: removed (5,0) //v </li></ul><ul><li>6: removed (6,2) //returned </li></ul><ul><li>2: removed (5,0) //b </li></ul><ul><li>1: removed (1,2) //a </li></ul>
  13. 13. Вправа до передачі об'єктів параметрами <ul><li>Що зміниться в протоколі, якщо у виводі забрати сталу відсилку? </li></ul><ul><li>ostream& operator <<(ostream &os, Point u ) </li></ul><ul><li>{ </li></ul><ul><li>os<<'('<<u.x()<<','<<u.y()<<')'; </li></ul><ul><li>return os; </li></ul><ul><li>} </li></ul>
  14. 14. Без локальної змінної <ul><li>Point operator+ (Point u, Point v) </li></ul><ul><li>{ </li></ul><ul><li>/* Замість </li></ul><ul><li>Point res(u.x()+v.x(), u.y()+v.y()); </li></ul><ul><li>return res; </li></ul><ul><li>*/ </li></ul><ul><li>return Point ( u.x()+v.x(), u.y()+v.y() ); </li></ul><ul><li>} </li></ul>
  15. 15. Протокол 2 <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(5); </li></ul><ul><li>a+b; </li></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul><ul><li>1: created (1,2) //a </li></ul><ul><li>2: created (5,0) //b </li></ul><ul><li>3: copied (5,0) //v </li></ul><ul><li>4: copied (1,2) //u </li></ul><ul><li>5: created (6,2) //return </li></ul><ul><li>4: removed (1,2) //u </li></ul><ul><li>3: removed (5,0) //v </li></ul><ul><li>5: removed (6,2) //returned </li></ul><ul><li>2: removed (5,0) //b </li></ul><ul><li>1: removed (1,2) //a </li></ul>
  16. 16. Сталі відсилки <ul><li>Point operator + ( const Point & u, const Point & v) </li></ul><ul><li>{ </li></ul><ul><li>return Point ( u.x()+v.x(), u.y()+v.y() ); </li></ul><ul><li>} </li></ul>
  17. 17. Протокол 3 <ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>Point a(1,2); </li></ul><ul><li>Point b(1); </li></ul><ul><li>a+b; </li></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul><ul><li>1: created (1,2) //a </li></ul><ul><li>2: created (5,0) //b </li></ul><ul><li>3: created (6,2) //return </li></ul><ul><li>3: removed (6,2) //returned </li></ul><ul><li>2: removed (5,0) //b </li></ul><ul><li>1: removed (1,2) //a </li></ul>
  18. 18. Урок передачі параметрів <ul><li>Передаючи параметр і одержуючи результат, усвідомлюйте, з чим маєте справу: з оригіналом чи копією </li></ul>
  19. 19. Копіювання агрегатів <ul><li>class WrappedVector </li></ul><ul><li>{ </li></ul><ul><li>private: </li></ul><ul><li>static const int n; </li></ul><ul><li>double * v; </li></ul><ul><li>public : </li></ul><ul><li>WrappedVector(); </li></ul><ul><li>WrappedVector(const WrappedVector&); </li></ul><ul><li>~WrappedVector(); </li></ul><ul><li>}; </li></ul>
  20. 20. Копіювальний конструктор вектора <ul><li>WrappedVector:: </li></ul><ul><li>WrappedVector ( const WrappedVector& vec): </li></ul><ul><li>_v ( new double [_n]) </li></ul><ul><li>{ </li></ul><ul><li>if (_v==0) ; //do smth </li></ul><ul><li>for ( int i=0; i<_n; i++) </li></ul><ul><li>_v[i] = vec._v[i]; </li></ul><ul><li>return ; </li></ul><ul><li>} </li></ul>
  21. 21. Копіювальний конструктор за замовчуванням <ul><li>WrappedVector:: </li></ul><ul><li>WrappedVector ( const WrappedVector& vec): </li></ul><ul><li>_v ( vec._v) </li></ul><ul><li>{ } ; </li></ul><ul><li>// Чим закінчиться виконання програми ? </li></ul><ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>WrappedVector u, v(u) ; </li></ul><ul><li>return 64; // катастрофою!!! </li></ul><ul><li>} </li></ul>
  22. 22. Копіювання присвоєнням <ul><li>class WrappedVector </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>static const int n; </li></ul><ul><li>double * v; </li></ul><ul><li>public : </li></ul><ul><li>WrappedVector(); </li></ul><ul><li>WrappedVector( const WrappedVector&); </li></ul><ul><li>~WrappedVector(); </li></ul><ul><li>WrappedVector& operator = ( const WrappedVector&); </li></ul><ul><li>}; </li></ul>
  23. 23. Реалізація копіювального присвоєння <ul><li>WrappedVector& WrappedVector:: operator = ( const WrappedVector& vec) </li></ul><ul><li>{ </li></ul><ul><li>// Нам поталанило: vec і this мають одну й ту ж довжину </li></ul><ul><li>for ( int i=0; i<n; i++) </li></ul><ul><li>v[i] = vec.v[i]; </li></ul><ul><li>return * this ; </li></ul><ul><li>} </li></ul>
  24. 24. Присвоєння за замовчуванням <ul><li>WrappedVector& WrappedVector:: operator = ( const WrappedVector& vec) </li></ul><ul><li>{ </li></ul><ul><li>v = vec; </li></ul><ul><li>return * this ; </li></ul><ul><li>} </li></ul><ul><li>// Чим закінчиться виконання програми ? </li></ul><ul><li>int main () </li></ul><ul><li>{ </li></ul><ul><li>WrappedVector u, v; </li></ul><ul><li>u=v; </li></ul><ul><li>return 64; // катастрофою!!! </li></ul><ul><li>} </li></ul>
  25. 25. Вектори різної довжини <ul><li>class DissimilarVector </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>int _ n; //non static, non const( ? ) </li></ul><ul><li>double * _ v; </li></ul><ul><li>public : </li></ul><ul><li>DissimilarVector( int ); </li></ul><ul><li>DissimilarVector( const DissimilarVector&); </li></ul><ul><li>~DissimilarVector(); </li></ul><ul><li>DissimilarVector& operator=( const DissimilarVector&); </li></ul><ul><li>}; </li></ul>
  26. 26. Конструктор вектора <ul><li>DissimilarVector:: </li></ul><ul><li>DissimilarVector ( int len ) : </li></ul><ul><li>_ n ( len ), </li></ul><ul><li>_ v ( new double[n ]) </li></ul><ul><li>{ </li></ul><ul><li>if ( _ v==0) // throw exeption </li></ul><ul><li>for ( int i=0; i< _ n; i++) </li></ul><ul><li>_ v[i] = 0; </li></ul><ul><li>return ; </li></ul><ul><li>} </li></ul>
  27. 27. Копіювальний конструктор <ul><li>DissimilarVector:: </li></ul><ul><li>DissimilarVector ( const DissimilarVector& vec): </li></ul><ul><li>_n ( vec ._n), </li></ul><ul><li>_v ( new double [ vec ._n]) </li></ul><ul><li>{ </li></ul><ul><li>if (_v==0) // throw exeption </li></ul><ul><li>for ( int i=0; i<_n; i++) </li></ul><ul><li>_v[i] = vec._v[i]; </li></ul><ul><li>return ; </li></ul><ul><li>} </li></ul>
  28. 28. Чому атрибут _ n не може бути сталим? <ul><li>Спробуйте присвоєння за замовчуванням </li></ul><ul><li>Навіть копіювальне присвоєння, взагалі кажучи, не працюватиме </li></ul>
  29. 29. Копіювальне присвоєння <ul><li>DissimilarVector& DissimilarVector:: operator = ( const DissimilarVector& vec) </li></ul><ul><li>{ </li></ul><ul><li>//1. Видалити старий об'єкт </li></ul><ul><li>if ( this ==&vec) </li></ul><ul><li>return *this; </li></ul><ul><li>delete [] _ v; </li></ul><ul><li>//2. Створити новий об'єкт </li></ul><ul><li>_ n = vec. _ n; </li></ul><ul><li>_ v = new double [ _ n]; </li></ul><ul><li>//1. Скопіювати значення </li></ul><ul><li>for ( int i=0; i< _ n; i++) </li></ul><ul><li>_ v[i] = vec. _ v[i]; </li></ul><ul><li>return * this ; </li></ul><ul><li>} </li></ul>_ n = vec. _ n
  30. 30. Рядки з копіюванням <ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; </li></ul><ul><li>char * _allocator; </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char *); </li></ul><ul><li>String( const char ); </li></ul><ul><li>String ( const String & s); </li></ul><ul><li>~String(); </li></ul><ul><li>}; </li></ul>
  31. 31. Копіювальний конструктор рядка <ul><li>String::String(String& s) </li></ul><ul><li>_len( s._len), </li></ul><ul><li>_allocator( new char [_len+1]) </li></ul><ul><li>{ </li></ul><ul><li>strcpy(_allocator, s._allocator); </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  32. 32. Редагування оригіналу (без const) <ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>private : </li></ul><ul><li>size_t _len; </li></ul><ul><li>char * _allocator; </li></ul><ul><li>int _amountOfCopies ; </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char *); </li></ul><ul><li>String( const char ); </li></ul><ul><li>String (String & s); </li></ul><ul><li>~String(); </li></ul><ul><li>}; </li></ul>
  33. 33. Копіювання з редагуванням <ul><li>String::String(String& s) </li></ul><ul><li>_amountOfCopies (0), </li></ul><ul><li>_len( s._len), </li></ul><ul><li>_allocator( new char [_len+1]) </li></ul><ul><li>{ </li></ul><ul><li>// Кількість копій, зроблених з оригіналу </li></ul><ul><li>// збільшується на одиницю </li></ul><ul><li>s._amountOfCopies++; </li></ul><ul><li>strcpy(_allocator, s._allocator); </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  34. 34. Мультиконструктор копіювання <ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char *); </li></ul><ul><li>String( const char ); </li></ul><ul><li>String( const String & s, int multiplayer=1); </li></ul><ul><li>~String(); </li></ul><ul><li>}; </li></ul>
  35. 35. Реалізація мультиконструктора копіювання <ul><li>String:: String( const String & s, int multiplayer): </li></ul><ul><li>_len (s._len*multiplayer), </li></ul><ul><li>_allocator ( new char [_len+1]) </li></ul><ul><li>{ </li></ul><ul><li>char * target = _allocator; </li></ul><ul><li>for ( int i=0; i<multiplayer; i++) </li></ul><ul><li>{ </li></ul><ul><li>strcpy(target, s._allocator); </li></ul><ul><li>target+=s._len; </li></ul><ul><li>} </li></ul><ul><li>return ; </li></ul><ul><li>}; </li></ul>
  36. 36. Застосування копіювання <ul><li>// Common constructor </li></ul><ul><li>String s(p); </li></ul><ul><li>// Copy version of multiplication constructor </li></ul><ul><li>String ss(s); </li></ul><ul><li>// Multiplication constructor </li></ul><ul><li>String s10(s,10); </li></ul>
  37. 37. Проблема замовчуваного параметру <ul><li>Що станеться, якщо замовчуваний параметр перенести до реалізації? ― Катастофа </li></ul><ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>String( const String & s, int multiplayer); </li></ul><ul><li>}; </li></ul><ul><li>String:: String( const String & s, int multiplayer =1 ): …{…;} </li></ul><ul><li>Чому? </li></ul>
  38. 38. Некоректне копіювання <ul><li>// Common constructor </li></ul><ul><li>String s(p); </li></ul><ul><li>// Default copy constructor </li></ul><ul><li>String ss(s); </li></ul><ul><li>// Multiplication constructor </li></ul><ul><li>String s10(s,10); </li></ul>
  39. 39. Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void operator =( T&) ; </li></ul><ul><li>T operator =( T&) ; </li></ul><ul><li>T& operator =( T ) ; </li></ul><ul><li>T operator =( T ) ; </li></ul><ul><li>T& operator =( T & ) ; </li></ul>
  40. 40. Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void operator =( T&) ; </li></ul><ul><li>T operator =( T&) ; </li></ul><ul><li>T& operator =( T ) ; </li></ul><ul><li>T operator =( T ) ; </li></ul><ul><li>T& operator =( T & ) ; </li></ul>T& operator =( const T & ) ;
  41. 41. Сигнатури присвоєнь <ul><li>Якій з сигнатур віддати перевагу? </li></ul><ul><li>void operator =( T&) ; // Як бути з x=y=z; </li></ul><ul><li>T operator =( T&) ; // чим копіювати результат? </li></ul><ul><li>T& operator =( T ) ; // чим копіювати параметр? </li></ul><ul><li>T operator =( T ) ; // див 2 і 3 разом </li></ul><ul><li>T& operator =( T & ) ; // ОК!!! </li></ul>
  42. 42. Що таке this? <ul><li>class T </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>T(T1,…,Tn); </li></ul><ul><li>~T(); </li></ul><ul><li>T( const T&); </li></ul><ul><li>T& operator = ( const T&); </li></ul><ul><li>}; </li></ul><ul><li>this має тип T * const </li></ul>
  43. 43. Чому * const ? <ul><li>this не можна перемістити на інший об'єкт </li></ul><ul><li>this = anything; не коректно </li></ul>
  44. 44. Повернення значення в присвоєнні <ul><li>Point& Point:: operator =( const Point & u) </li></ul><ul><li>{ </li></ul><ul><li>this ->_x = u._x; </li></ul><ul><li>* this ._y = u._y; </li></ul><ul><li>return * this ; </li></ul><ul><li>} </li></ul>
  45. 45. Рядки з присвоєнням <ul><li>class String </li></ul><ul><li>{ </li></ul><ul><li>public : </li></ul><ul><li>String(); </li></ul><ul><li>String( const char *); </li></ul><ul><li>String( const char ); </li></ul><ul><li>String( const String & s, int multiplayer=1); </li></ul><ul><li>String& operator =( const String&); </li></ul><ul><li>~String(); </li></ul><ul><li>}; </li></ul>
  46. 46. Присвоєння рядків <ul><li>String& String:: operator =( const String& s) </li></ul><ul><li>{ </li></ul><ul><li>if ( this ==&s) </li></ul><ul><li>return * this ; </li></ul><ul><li>delete [] _allocator; </li></ul><ul><li>_len = s._len; </li></ul><ul><li>_allocator = new char [_len+1]; </li></ul><ul><li>strcpy(_allocator, s._allocator); </li></ul><ul><li>return *this ; </li></ul><ul><li>} </li></ul>
  47. 47. Висновки <ul><li>Конструктор копіювання створює новий об'єкт </li></ul><ul><li>Присвоєння звичайно замінює існуючий об'єкт іншим об'єктом (навіть якщо не доводиться видаляти попередні значення) </li></ul><ul><li>Присвоєння не можна визначити поза класом </li></ul><ul><li>Присвоєння в класі T має тип T& (чому?) </li></ul><ul><li>Присвоєння повертає *this , конструктори не повертають нічого (чому?) </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×