- •Конструкторы и деструкторы
- •Формат компонентной функции-деструктора
- •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( )
Конструктор копирования
Назначение:
создать объект полностью совпадающий с уже созданным;
передача в некоторую функцию экземпляра класса, при этом в стеке создается локальная копия объекта, с которым и работает функция;
функция передает в некоторую переменную объект класса, фактически этот объект сначала создается в функции как локальная переменная, и лишь затем копируется в переменную, стоящую в левой части выражения.
Операции копирования объектов выполняет конструктор копирования.
В большинстве случаев компилятор предоставляет нам конструктор копирования по умолчанию, обеспечивая правильное копирование.
Копирование по умолчанию:
class T {
int x, y ;
public:
T ( int tx , int ty ) { x = tx ; y = ty ; }
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= 1 y = 10
x= 1 y = 10
x= 2 y = 20
Определение конструктора копирования
Конструктор копирования должен иметь для данного класса такой вид:
1. T ( T obj ) { x = obj.x ; y = obj. y } // не верно!
Но тогда в сам конструктор копирования должен копироваться объект, т.е. должен вызываться сам конструктор копирования, в котором опять для копирования будет вызываться сам конструктор. Возникла бы бесконечная рекурсия.
Рекурсию можно избежать, если не копировать объект в конструктор, а использовать передачу параметра по ссылке:
2. T ( T & obj ) { x = obj.x ; y = obj. y }
И последнее – необходимо ввести запрет на модификацию копируемого параметра для этого используется ключевое слово const:
3. T ( const T & obj ) { x = obj.x ; y = obj. y }
В общем случае третий вариант наиболее правильный (и так выглядит конструктор по умолчанию), однако структура конструкторов, такова, что в них отсутствуют действия, изменяющие копируемый объект. Поэтому в дальнейшем часто будем останавливаться на втором варианте.
Рассмотрим, как происходит копирование.
Как удостоверится, что
- при копировании объекта,
- при передачи объекта в функцию,
-при возвращении функцией объекта в некоторую
переменную (также объект)
вызывается конструктор копированияпо умолчанию, иликонструктор копирования явно определенный в классе?
Для того, чтобы зафиксировать факт вызова конструктора копирования, мы правильное копирование (в программе написанной выше, конструктор варианта 3 вызывается по умолчанию) заменим на копирование с приращением:
class T {
int x, y ;
public:
T ( int tx , int ty ) { x = tx ; y = ty ; }
T (const T & obj) { x = obj.x+1 ; y = obj. y +1 }