02 Copying Objects

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Favorites, Groups & Events

    02 Copying Objects - Presentation Transcript

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

    + olegapsterolegapster Nominate

    custom

    66 views, 0 favs, 0 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 66
      • 66 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 0
    • Downloads 0
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories