Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические указания.doc
Скачиваний:
9
Добавлен:
18.04.2015
Размер:
619.52 Кб
Скачать

Конструктор и деструктор

Конструктор представляет собой нестатический конечный метод, вызываемый в момент создания объекта для его инициализации. Особенностью конструктора является то, что он не может иметь возвращаемой переменной. Код вызова конструктора вставляется в объектный код программы компилятором автоматически, прозрачно для программиста, каждый раз, когда выполняется команда создания нового объекта (будь то в куче или стеке, см. ниже про виды памяти).

Класс может иметь несколько конструкторов, отличающихся сигнатурой. Если в ходе создания объекта в его конструктор не передаются параметры, то вызывается конструктор без параметров, называемый конструктором по умолчанию. Если для класса не определен конструктор по умолчанию, то объект создается в памяти без выполнения инициализации, что приводит к случайным значениям его переменных (кроме неявного указателя на таблицу виртуальных функций – он заполняется верным значением в любом случае). Например, в следующем случае будет вызван конструктор по умолчанию, если он объявлен в классе «водитель»:

Person * p = new Driver;

Если в ходе создания объекта параметры конструктора указаны явно, например,

Person * p = new Driver (10);

то будет вызван конструктор, сигнатура которого соответствует передаваемым параметрам. Если такой конструктор не будет найден, или возникнет неоднозначность, будет выдана соответствующая ошибка компилятора.

В случае наследования, до вызова конструктора производного класса обязательно вызывается конструктор базового класса. При этом, если конструкторов базового класса несколько, то в объектно-ориентированном языке существует возможность указать какой именно конструктор вызывать. Например, на языке C++ это можно сделать следующим образом:

class Driver: public Person {

Driver ():Person(0){}

};

если для класса «персона» объявлен конструктор, принимающий целое число в качестве параметра.

Если же не указан ни один из конструкторов, то вызывается конструктор по умолчанию. Даже если в производном классе не объявлен конструктор, конструктор по умолчанию базового класса все равно будет вызван. Например, в случае

class Driver: public Person {

};

при создании объекта класса «водитель» всегда будет вызываться конструктор по умолчанию для класса «персона», если он объявлен.

Деструктор представляет собой нестатический метод, вызываемый в момент уничтожения объекта. Деструктор, как и конструктор, не имеет возвращаемой переменной. К тому же, деструктор не имеет параметров, и класс может иметь только один деструктор. Код вызова деструктора вставляется в объектный код программы компилятором прозрачно для программиста каждый раз, когда некоторый объект прекращает свое существование (будь то в стеке или куче). Если для класса деструктор не задан, то память, выделенная под объект, освобождается без каких-либо дополнительных действий. В случае, если объект захватил некоторые ресурсы (например, память или файловые дескрипторы), отсутствие деструктора приведет к тому, что они будут потеряны для дальнейшего использования в программе. Поэтому, для корректной работы программы, классы, захватывающие ресурсы, необходимо дополнять деструктором, освобождающим эти ресурсы.

В случае наследования, компилятор для уничтожения объекта помещает в объектный код программы вызов как деструктора производного класса, так и деструктора базового. При этом, сначала выполняется вызов деструктора производного класса. Только после вызова деструкторов всех предков, вызывается деструктор самого класса, после чего память, выделенная под объект, освобождается.

Деструктор может быть динамическим. В этом случае, в ходе удаления объекта, будет выполнена последовательность вызовов деструкторов именно для того объекта, который располагается в памяти, а не того объекта, на который показывает указатель. Эту особенность можно проиллюстрировать на следующем примере:

Person * p = new Driver;

delete p;

В этом примере, если деструктор класса «персона» виртуальный, то в ходе уничтожения объекта, в соответствии с правилом динамического связывания и правилом вызова деструкторов, будет вызван сначала деструктор класса «персона», затем деструктор класса «водитель». Если деструктор класса «персона» не является виртуальным, то в ходе уничтожения объекта, в соответствии с правилом статического связывания и правилом вызова деструкторов, будет вызван только деструктор класса «персона», так как удаляемый указатель показывает на объект класса «персона».