Деструкторы. Определение деструктора. Общедоступные и приватные деструкторы. Примеры использования деструкторов. Отличия между конструкторами и деструкторами

Деструкторы. Определение деструктора. Общедоступные и приватные деструкторы. Примеры использования деструкторов. Отличия между конструкторами и деструкторами


Содержание



1. Какое назначение деструктора в классе?

Деструктор, как и конструктор, относится к специальным функциям класса. Деструктор – это специальный метод, который вызывается при удалении объекта. Как правило, деструктор используется для освобождения памяти, динамично выделенной под внутренние данные класса. Могут быть и другие случаи применения деструктора.

Деструктор – это обратная по отношению к конструктору функция.

Имя деструктора совпадает с именем класса, перед которым следует символ ‘~’. Например, если класс имеет имя CMyClass, тогда имя деструктора будет ~CMyClass().

2. Пример использования общедоступного деструктора

Пусть задан класс, который определяет массив структур типа DATE. Каждая структура в массиве описывает дату в формате: число, месяц, год. В классе объявлен ряд конструкторов, методов а также деструктор, который освобождает память для массива.

Общий код модуля, в котором объявляется структура и класс.

// структура, реализующая дату
struct DATE
{
    int day;
    int month;
    int year;
};

// класс, определяющий массив структур типа DATE
class CDates
{
    int n;
    DATE *A; // массив структур

    public:
    CDates(void); // конструктор по умолчанию
    ~CDates(void); // деструктор

    // методы класса
    void Set(int nn); // установить новое значение n, выделить заново память для массива A
    DATE GetDATE(int index); // возвратить значение структуры с индексом index
};

// конструктор по умолчанию
CDates::CDates(void)
{
    n = 0;
}

// деструктор
CDates::~CDates(void)
{
    // освобождение памяти, выделенной для массива структур
    delete A;
}

// установить новое значение n
void CDates::SetN(int nn)
{
    // 1. Освободить предыдущую память
    // освободить память, выделенную под массив структур
    delete A;

    // 2. Установить новое n
    n = nn;

    // 3. Выделить память для массива указателей на структуру типа (DATE *)
    A = new DATE[n];

    // заполнить поля каждой структуры произвольными значениями
    for (int i=0; i<n; i++)
    {
        A[i].day = i;
        A[i].month = i%12 + 1;
        A[i].year = 1000*i;
    }
}

// возвратить значение структуры с индексом DATE
DATE CDates::GetDATE(int index)
{
    return (DATE)A[index];
}

Демонстрация использования данного класса в другом методе.

CDates CD; // объявить объект типа CDates, вызывается конструктор по умолчанию

// установить новое значение n
CD.Set(8);

// проверка
int t;
DATE D;
D = CD.GetDATE(5); // взять структуру с индексом 5

t = D.day; // t = 5
t = D.year; // t = 5000

// после выхода из метода, объект CD уничтожается, а, значит, вызывается деструктор ~CDates
// который освобождает память для массива A в классе

3. Можно ли деструктор объявить в разделе private?

Да, можно. Такой деструктор называется приватным деструктором.

4. В каких случаях целесообразно объявлять приватные деструкторы?

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

5. Какие ограничения возникают при работе с объектами класса, если в классе объявлен приватный деструктор?

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

  • невозможно создать автоматический объект класса (объект класса, который объявляется в некотором методе);
  • невозможно создать статический объект;
  • невозможно создать глобальный объект класса.

Это связано с тем, что такие объекты в дальнейшем невозможно будет уничтожить.

Например. Пусть задан класс, в котором объявлен приватный деструктор.

class CMyInt
{
    private:
    int n; // количество элементов массива

    // деструктор, объявленный в разделе private
    ~CMyInt(void);

    public:
    CMyInt(void);

    // методы класса
    void SetN(int nn) { n = nn; }
    int GetN(void) { return n; }
};

Если попробовать создать объект класса в другом программном коде

CMyInt MI;

то компилятор выдаст ошибку

'CMyInt::~MyInt': cannot access private member declared in class 'CMyInt'

Однако, можно объявлять указатель на класс CMyInt. Следующее описание будет правильным

// приватный деструктор
CMyInt * pMI = new CMyInt; // можно объявлять указатель на класс, содержащий приватный деструктор

6. Может ли деструктор иметь параметры?

Деструктор не может иметь параметров.

7. Какие основные отличия между использованием конструкторов и деструкторов в классах?

При использовании в классе, между конструктором и деструктором можно определить следующие основные отличия:

  • деструкторам нельзя передавать параметры, конструкторам можно;
  • деструкторы могут быть виртуальными, конструкторы – нет;
  • при объявлении класса, можно объявить только один деструктор. Однако, конструкторов можно объявлять сколько угодно. Главное, чтобы они отличались сигнатурой.


Связанные темы