Возможно вы заметили, что определяя класс, мы не можем инициализировать его поля (члены) в самом определении. Можно присвоить им значение, написавши відповідний метод класу і викликавши його, после создания объекта вне класса. Такой способ не совсем удобен, так как объявляя, припустимо, 33 об'єкта класу нам доведеться 33 раза вызывать метод, який присвоює значення полів класу. Тому, як правило, для ініціалізації полів класу, а так само для виділення динамічної пам'яті, используется конструктор.
конструктор(от construct – создавать) – это особый метод класса, который выполняется автоматически в момент создания объекта класса. То есть, если мы пропишем в нем, какими значениями надо инициализировать поля во время объявления объекта класса, он сработает без “особого приглашения”. Его не надо специально вызывать, как обычный метод класса.
Приклад:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #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. При запуске программы, конструктор этого объекта сработает даже до входа в главную функцию. Это видно на следующем снимке:
программа еще не дошла до выполнения строки 29 setlocale(LC_ALL, "rus"); , а конструктор уже “отчитался”, что сработал (кириллица отобразилась некорректно). В рядку 30 – смотрим, что содержат поля класса. Второй раз конструктор сработает в строке 32, під час створення об'єктаobj2.
Деструктор (от destruct – разрушать) – так же особый метод класса, который срабатывает во время уничтожения объектов класса. Чаще всего его роль заключается в том, чтобы освободить динамическую память, которую выделял конструктор для объекта. Имя его, как и у конструктора, должно соответствовать имени класса. Только перед именем надо добавить символ ~
Добавим деструктор в предыдущий код. И создадим в классе два конструктора: один буде приймати параметри, второй – нет.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #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;
- Конструктор и деструктор не имеют типа возвращаемого значения;
- Имена класса, конструктора і деструктора повинні збігатися;
- Конструктор может принимать параметры. Деструктор не принимает параметры;
- При визначенні деструкції перед ім'ям треба додати символ ~ ;
- Конструкторов может быть несколько, но их сигнатура должна отличаться (кількістю прийнятих параметрів, например);
- Деструкція в класі повинен бути визначений тільки один.
Я так зрозумів я з автором живу в різних часових поясах, а то у мене ще 09.11.14
веселощі :)
Да – у нас тут в Японії 10-е наступило на 2 дні раніше )) А завтра так взагалі 31-е грудня буде!
>> Один об'єкт оголошується відразу під час визначення класу - рядок 25. При запуску програми конструктор цього об'єкту спрацює навіть до входу в головну функцію.
Зовсім не важливо відразу “під час визначення” або потім. Викликається він раніше, тому що це глобальний об'єкт.
>> Чаще всего его роль заключается в том, чтобы освободить динамическую память, которую выделял конструктор для объекта.
Якщо об'єкт виділяє всередині себе пам'ять – то так, треба писати руками деструктор і звільняти її.
Але у вашому випадку динамічна пам'ять не виділяється, а деструкція таки потрібен (він коректно повинен знищити об'єкт). Але в вашому прикладі його можна було і не писати зовсім – якщо деструктора в класі немає – то буде створено деструктор за замовчуванням – він видалить коректно об'єкт, але пам'ять, розподілену динамічно природно не звільнить.
Однак є в С ++ розумні покажчики і якщо використовувати їх – то майже завжди можна покладатися на деструкцію за замовчуванням )).
Чи не порушена купа питань по темі статті, например:
– список ініціалізації конструктора;
– віртуальний деструктор;
– конструктор копіювання;
– конструктори за умовчанням;
– виключення в конструкторах і деструктори;
– т .p.
Воно все буде описано? )
цей милий смайлик в кінці коментаря…
Конечно, ще будуть статті. Конструктор копіювання – обов'язково в окремій статті розглянемо. Про конструкторах за замовчуванням – додам до цієї статті.
setlocale(LC_ALL, “rus”);
щось в прикладі з конструктором кодування російська працює, а в прикладі з деструкцією – нет. =:(
Як спрацював деструктор? В ІНТ основний() його ж таки не прописали
конструктор (от construct – создавать) - це особливий метод класу, який виконується автоматично в момент створення об'єкту класу.
І він таки при автоматичному видаленні локальних змінних всередині блоку main.
ув1акб