Бьерн Страуструп - Язык программирования С++. Вступление, глава 1 - Инициализация и удаление

ОГЛАВЛЕНИЕ

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).