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

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

Конструктор (от construct – создавать) — это особый метод класса, который выполняется автоматически в момент создания объекта класса. То есть, если мы пропишем в нем, какими значениями надо инициализировать поля во время объявления объекта класса, он сработает без «особого приглашения». Его не надо специально вызывать, как обычный метод класса.

Пример:

#include <iostream>

using namespace std;

 

class SomeData

{

private:

int someNum1;

double someNum2;

char someSymb[128];

public:

SomeData() //это конструктор:

{

someNum1 = 111; // присваиваем начальные значения полям

someNum2 = 222.22;

strcpy_s(someSymb, "СТРОКА!");

cout << "\nКонструктор сработал!\n";

}

 

void showSomeData()

{

cout << "someNum1 = " << someNum1 << endl;

cout << "someNum2 = " << someNum2 << endl;

cout << "someSymb = " << someSymb << endl;

}

}obj1; //уже на этом этапе сработает конструктор (значения запишутся в поля)

 

int main()

{

setlocale(LC_ALL, "rus");

obj1.showSomeData();

 

SomeData obj2; //тут сработает конструктор для второго объекта класса

obj2.showSomeData();

}

В строках 11 — 17 определяем конструктор: имя должно быть идентично имени класса; конструктор НЕ имеет типа возвращаемого значения (void в том числе). Один объект объявляется сразу во время определения класса — строка 25. При запуске программы, конструктор этого объекта сработает даже до входа в главную функцию. Это видно на следующем снимке:

программа еще не дошла до выполнения строки 29setlocale(LC_ALL, "rus"); , а конструктор уже «отчитался», что сработал (кириллица отобразилась некорректно). В строке 30 — смотрим, что содержат поля класса. Второй раз конструктор сработает в строке 32, во время создания объекта obj2.

Деструктор (от destruct — разрушать) — так же особый метод класса, который срабатывает во время уничтожения объектов класса. Чаще всего его роль заключается в том, чтобы освободить динамическую память, которую выделял конструктор для объекта. Имя его, как и у конструктора, должно соответствовать имени класса. Только перед именем надо добавить символ ~

Добавим деструктор в предыдущий код. И создадим в классе два конструктора: один будет принимать параметры, второй — нет.

#include <iostream>

using namespace std;

 

class SomeData

{

private:

int someNum1;

double someNum2;

char someSymb[128];

public:

SomeData()

{

someNum1 = 0;

someNum2 = 0;

strcpy_s(someSymb, "СТРОКА ПО УМОЛЧАНИЮ!");

cout << "\nКонструктор сработал!\n";

}

 

SomeData(int n1, double n2, char s[])

{

someNum1 = n1;

someNum2 = n2;

strcpy_s(someSymb, s);

cout << "\nКонструктор с параметрами сработал!\n";

}

 

void showSomeData()

{

cout << "someNum1 = " << someNum1 << endl;

cout << "someNum2 = " << someNum2 << endl;

cout << "someSymb = " << someSymb << endl;

}

 

~SomeData()

{

cout << "\nДеcтруктор сработал!\n";

}

};

 

int main()

{

setlocale(LC_ALL, "rus");

SomeData obj1(1, 2.2, "СТРОКА ПАРАМЕТР"); // сработает конструктор с параметрами

obj1.showSomeData();

 

SomeData obj2; // сработает конструктор по умолчанию

obj2.showSomeData();

}

Деструктор определен в строках 34 — 37. Для простоты примера он просто отобразит строку в том месте программы, где сработает. Строка 43 — объявляем объект класса и передаем данные для записи в поля. Тут сработает конструктор с параметрами. А в строке 46 — сработает конструктор по умолчанию.

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

Важное:

  • Конструктор и деструктор должны быть public;
  • Конструктор и деструктор не имеют типа возвращаемого значения;
  • Имена класса, конструктора и деструктора должны совпадать;
  • Конструктор может принимать параметры. Деструктор не принимает параметры;
  • При определении деструктора перед именем надо добавить символ ~ ;
  • Конструкторов может быть несколько, но их сигнатура должна отличаться (количеством принимаемых параметров, например);
  • Деструктор в классе должен быть определен только один.