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

Void main ( )

{ My a1 (10) ; // создается объект, переменная инициализируется 10

My a2 = a1; // с помощью конструктора копирования создается объект

// a2, со значением переменной 11, т.к. в конструкторе

//инкремент

Print ( a1) ;

/* значение переменной объекта a1 копируется с инкрементом в

в переменную локального объекта obj функции (11 ) и это

значение выводится */

Print ( a2 ) ;

/* значение переменной объекта a2 копируется с инкрементом в

в переменную локального объекта obj функции (12 ) и это

значение выводится */

a1. ~My( ) ; // вызовом деструктора объект памятьa1освобождается

Print ( a1) ; // выведется мусор

Print ( a2); // выведется 12

}

Результат:

11

12

7853

12

После вызова деструктораa1 освобождается динамическая память и в данном (*p) – члене объектаa1 содержится теперь мусор (операцияdeleteв процессе возврата в систему возвращаемой памяти затирает эту память).

Объект a2 остался неизменным. Так и должно быть.

Если мы удалим из определения класса конструктор копирования, результат работы программы следующий:

10

10

7853

7853

Уничтожение объекта a1привело к уничтожению и его копииa2, в которой находится теперь тот же мусор.

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

При отсутствии конструктора копирования программа будет использовать конструктор копирования по умолчанию следующего вида:

My ( My & obj ) { p = obj.p; }

В объекте a1 находится указатель на выделенное обычным конструктором поле памяти.

Побайтовое копирование объекта дает копирование указателя, т.е. в объект a2заносится тот же самый указатель, оба объекта указывают на один и тот же участок памяти.

Объект a1

P

10

Данное(*p)

Объект

P

a2

При освобождении памяти в a1 ( или вa2 ) стирается наше единственное данное, т.е. и второй объект разрушается.

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

Объект a1

P

10

Данное( *p)

P

10

Объект a2

Данное(*p)

В этом случае объекты a1иa2 будут указывать на разные поля. Уничтожение одного из них вызовом деструктора, никак не отразится на существовании другого. Именно это и выполняется в нашем конструкторе копирования.

Еще о конструкторах

Есть еще один способ инициализации объекта с помощьюсписка инициализаторовданных объекта.

Этот список помещается при описании конструктора между списком параметров и телом конструктора:

<имя класса> ( список параметров) : < список инициализаторов>

{ тело конструктора }

Пример :

Class A

{ int ii ; float ee ; char cc;

public : A( int i , float e , char c ) : ii ( 7),

ee( ii + i * e),

cc(c)

{ }

. . .

};

A a( 5 , 1.2 . f’) ; // создается объект с компонентами a.ii =7 ,

// a.ee = 13 , a.cc=’f’

- Параметром конструктора не может быть его собственный класс, но

может быть ссылка на него.

- В классе может быть несколько конструкторов, но только один с

умалчиваемыми значениями параметров.

- Нельзя получить адрес конструктора.

- Если в определении класса нет конструктора, то компилятор автоматически предоставляет конструктор по умолчанию, который и создает неинициированный объект

<Имя класса> < имя объекта>;

Если есть хоть один конструктор с параметрами (но без значений по- умолчанию), для того чтобы иметь возможность создать неинициированный объект надо объявить в теле класса конструктор по умолчанию:

<Имя класса> ( ) { };

тогда используя конструкцию

<Имя класса> < имя объекта>;

можно объявить неинициированный объект.

Примеры:

1.

сlass Book {

public :

char title[40];

char author[20];

float price;

Book ( char*atitle, char*aauthor, float aprice ); //прототип

//конструктора

~Book( ) ; // прототип деструктора

void show_book(void) { cout<<’\n’<< title<< “, “<<price ;}

} ;

Book::Book(char*atitle, char*aauthor, float aprice )

{ strcpy(title, atitle); strcpy(author, aauthor);

price = aprice; }

Book::~Book( )

{ cout <<’\n’<< “Уничтожение экземпляра:”<< title ;}