- •Конструкторы и деструкторы
- •Формат компонентной функции-деструктора
- •Void main () {
- •Void main()
- •Void main()
- •Конструктор с аргументами, задаваемыми по умолчанию
- •Void main ()
- •Void shownumber ( void)
- •Конструктор по умолчанию
- •Конструктор копирования
- •Int GetX ( ) { return X; }
- •Int GetX ( ) { return X; }
- •Int GetY ( ) { return y; }
- •Void Print ( t obj )
- •Void main () {
- •Void main ( )
- •Void main ( )
- •Void vivod ( ) // выводит данные
- •Void main ( )
- •Имя класса ::имя компонента
- •Void main ( )
- •Тип данных(имя класса ::*имя указателя)
- •Имяобъекта.* указатель на компонент данных;
- •Имя объекта.*указатель на метод(параметры);
- •Компонентные функции
- •Initgraph( тип графического драйвера, режим адаптера , путь к драйверу)
- •Void far initgraph (int far * graphdriver, int far * graphmode, char far * pathtodriver);
- •Void point :: show (void)
- •Void point :: hide(void)
- •Void main ( )
- •Указатель this
- •Void print ( void) void print ( void)
- •Void main ()
- •Void que::add(void)
- •Void que::print (void)
- •Void main( )
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
При освобождении памяти в a1 ( или вa2 ) стирается наше единственное данное, т.е. и второй объект разрушается.
Правильным копированием при наличии в объекте динамического данного будет выделение для создаваемого при копировании объекта нового участка памяти.
Объект a1
P 10
Данное( *p)
P 10
Данное(*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 ;}