Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
1
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

1.4.1 Инициализация и удаление

      Когда представление типа скрыто, необходимо дать пользователю средства для инициализации переменных этого типа. Простейшее решение - до использования переменной вызывать некоторую функцию для ее инициализации. Например:       class vector       {       // ...       public:       void init ( init size ); // вызов init () перед первым       // использованием объекта vector       // ...       };       void f ()       {       vector v;       // пока v нельзя использовать       v.init ( 10 );       // теперь можно       }       Но это некрасивое и чреватое ошибками решение. Будет лучше, если создатель типа определит для инициализации переменных некоторую специальную функцию. Если такая функция есть, то две независимые операции размещения и инициализации переменной совмещаются в одной (иногда ее называют инсталляцией или просто построением). Функция инициализации называется конструктором. Конструктор выделяется среди всех прочих функций данного класса тем, что имеет такое же имя, как и сам класс. Если объекты некоторого типа строятся нетривиально, то нужна еще одна дополнительная операция для удаления их после последнего использования. Функция удаления в С++ называется деструктором. Деструктор имеет то же имя, что и его класс, но перед ним стоит символ ~ (в С++ этот символ используется для операции дополнения). Приведем пример:       class vector       {       int sz; // число элементов       int * v; // указатель на целые       public:       vector ( int ); // конструктор       ~vector (); // деструктор       int& operator [] ( int index ); // операция индексации       };       Конструктор класса vector можно использовать для контроля над ошибками и выделения памяти:       vector::vector ( int s )       {       if ( s <= 0 )       error ( "недопустимый размер вектора" );       sz = s;       v = new int [ s ]; // разместить массив из s целых       }       Деструктор класса vector освобождает использовавшуюся память:       vector::~vector ()       {       delete [] v; // освободить массив, на который       // настроен указатель v       }       От реализации С++ не требуется освобождения выделенной с помощью new памяти, если на нее больше не ссылается ни один указатель (иными словами, не требуется автоматическая "сборка мусора"). В замен этого можно без вмешательства пользователя определить в классе собственные функции управления памятью. Это типичный способ применения конструкторов и деструкторов, хотя есть много не связанных с управлением памятью применений этих функций (см., например, $$9.4).

1.4.2 Присваивание и инициализация

      Для многих типов задача управления ими сводится к построению и уничтожению связанных с ними объектов, но есть типы, для которых этого мало. Иногда необходимо управлять всеми операциями копирования. Вернемся к классу 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&) используются для передачи параметров по значению и получения возвращаемого функцией значения.