Присваивание и инициализация
Для многих типов задача управления ими сводится к построению и уничтожению связанных с ними объектов, но есть типы, для которых этого мало. Иногда необходимо управлять всеми операциями копирования. Вернемся к классу vector:
void f ()
{
vector v1 ( 100 );
vector v2 = v1; // построение нового вектора v2,
// инициализируемого v1
v1 = v2; // v2 присваивается v1
// ...
}
Должна быть возможность определить интерпретацию операций инициализации v2 и присваивания v1. Например, в описании:
class vector
{
int * v;
int sz;
public:
// ...
void operator = ( const vector & ); // присваивание
vector ( const vector & ); // инициализация
};
указывается, что присваивание и инициализация объектов типа vector должны выполняться с помощью определенных пользователем операций. Присваивание можно определить так:
void vector::operator = ( const vector & a )
// контроль размера и копирование элементов
{
if ( sz != a.sz )
error ( "недопустимый размер вектора для =" );
for ( int i = 0; i < sz; i++ ) v [ i ] = a.v [ i ];
}
Поскольку эта операция использует для присваивания "старое значение"
вектора, операция инициализации должна задаваться другой функцией, например, такой:
vector::vector ( const vector & a )
// инициализация вектора значением другого вектора
{
sz = a.sz; // размер тот же
v = new int [ sz ]; // выделить память для массива
for ( int i = 0; i < sz; i++ ) //копирование элементов
v [ i ] = a.v [ i ];
}
В языке С++ конструктор вида T(const T&) называется конструктором
копирования для типа T. Любую инициализацию объектов типа T он выполняет с помощью значения некоторого другого объекта типа T. Помимо явной инициализации конструкторы вида T(const T&) используются для передачи параметров по значению и получения возвращаемого функцией значения.