Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конструкторы и деструкторы.doc
Скачиваний:
24
Добавлен:
18.04.2015
Размер:
184.83 Кб
Скачать

Int GetX ( ) { return X; }

Int GetY ( ) { return y; }

friend T sum ( T, T);

};

Void Print ( t obj )

{ cout<<’\n’<<”x=”<<obj.GetX( ) <<” y=”<<obj.GetY( ); }

T sum ( T obj1 , T obj2 ) // хотя закрытые данные функция -друг

{ obj1. x + =obj2. x ; // имеет право обращаться к компонентам

obj1. y + =obj2. y ;

return obj1 ; }

#include <iostream.h>

Void main () {

T e1 ( 1, 10); //создаем объект

Print ( e1 ); // первое копирование - приращение

T e2 = e1; // второе копирование

Print ( e2 ); // третье копирование

T e3 = sum ( e1, e2 ) ; // четвертые копирования

Print (e3); // пятое копирование

}

// выведется:

// x= 2 y = 11

x= 3 y = 12

x= 7 y = 25

  1. При копировании e1 в локальную переменную obj в функции Print,

в данные объекта obj передадутся значенияx и y объекта e1 с

инкрементом, которые и будут выведены функцией (x= 2y= 11)

  1. При копировании в e1 в e2 , в объектe2передадутся

инкрементированные значения x и y объектаe1 ( 2 и 11- значения

данных объекта e2).

  1. Затем при вызове Print(e2) , значения объектаe2копируются в локальную

переменную obj в функции Print.Вobj передадутся значенияx и y из

e2 с инкрементом они и будут выведены (x= 3y= 12).

4) Затем в локальные переменные obj1 obj2 функцииsum копируются

данные объектов e1 e2 с инкрементом вobj1 - (2 11), вobj2 - ( 3 12).

Локальные объекты суммируются в функции. Результирующий объект

имеет значения данных ( 5 23 ).

Данные этого объекта копируются с инкрементом в данные объекта e3 в

выражении T e3 = sum (…); т.е.e3 получает данные ( 6 24 ).

5) При вызове Print(e3) , значения объектаe3копируются в локальную

переменную obj в функции Print.Вobj передадутся значенияx и y из

e3 с инкрементом они и будут выведены (x= 7y= 25).

Как мы видели выше, копирование по умолчанию осуществляет правильное копирование и без определения конструктора копирования в классе. Свой конструктор копирования нужен не всегда.

Обязательное его определение в тех случаях, когда класс содержит поля, являющиеся указателями на динамические участки памяти.

#include <iostream.h>

#include <conio.h>

class My {

int* p;

public:

My ( int a) //встроенный конструктор с параметром

{ p= new int ; *p = a ; }

My ( const My & obj ) //конструктор копирования с инкрементом

{ p = new int ; *p = *obj.p+1 ; }

/*Для фиксации вызова конструктора копирование также проводится с

инкрементом.

Конструктор копирования, создавая копию объекта, сначала выделяет

память под данное- член нового объекта и затем присваивает ему

значение , взятое из объекта – аргумента. Правильное присваивание

( без инкремента): *p = *obj.p;

*/

int Get ( ) { return * p } //возвращает значение по адресу указателя

~My ( ) { delete (p); } //деструктор память, выделенную под данное

//объекта освобождает

} ;

void Print ( My obj ) // функция вывода на экран самой переменной

{ cout<< ‘\n’ << obj.Get ( ) ;}