Бьерн Страуструп - Язык программирования С++. Вступление, глава 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).