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

Классы & объекты C++

Конструктор класса

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

Имя конструктора точно совпадает с именем класса, и он не имеет возвращаемого типа (дажеvoidозначает, что b — это массив объектов класса AB, содержащий 3 объекта; следовательно, конструктор вызывается 3 раза;

означает, что p — это массив указателей на объекты класса AB, содержащий 4 указателя на объекты класса; конструктор не вызывается.

Следующий пример помогает лучше понять концепцию конструкторов:

Пример

#include <iostream> using namespace std; class Line { public: Line(); // Объявление конструктора void setLength(double len); double getLength() const; private: double length; }; // Определение конструктора Line::Line() { cout << "Объект создается" << endl; length = 0.0; // Явная инициализация переменных-членов } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // Главная функция программы int main() { Line line; // Установить длину line.setLength(6.0); cout << "Длина линии : " << line.getLength() << endl; return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

Object is being created
Length of line : 6

Параметризованные конструкторы

Конструктор по умолчанию не имеет параметров, но при необходимости конструкторы также могут иметь параметры. Таким образом, начальные значения присваиваются объекту при его создании без необходимости отдельного вызоваsetфункции, как показано в следующем примере:

Пример

#include <iostream> using namespace std; class Line { public: Line(double len); // Объявление конструктора с параметрами void setLength(double len); double getLength() const; private: double length; }; // Определение конструктора Line::Line(double len) { cout << "Создаётся объект, длина = " << len << endl; length = len; } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // Главная функция программы int main() { Line line(10.0); // Передайте начальную длину непосредственно при создании объекта // Получить начальную длину cout << "Длина линии : " << line.getLength() << endl; // Сбросить длину line.setLength(6.0); cout << "Длина линии : " << line.getLength() << endl; return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

Object is being created, length = 10
Length of line : 10
Length of line : 6

Использование списков инициализации для инициализации полей

C++ рекомендует использоватьсписок инициализации членовдля инициализации переменных-членов. Его синтаксис — добавить двоеточие после списка параметров конструктора,:), затем напишитеmember variable name (initial value)。

В следующем примере,: length(len)означает: использовать переданный параметрlenдля непосредственной инициализации переменных-членовlength. ПримечаниеcoutВыводится переменная-членlength, а не параметрlenпозволяя вам интуитивно проверить, что переменные-члены были правильно присвоены:

Line::Line(double len) : length(len) { // На этом этапе length был присвоен через список инициализации; выведите length, чтобы проверить результат cout << "Объект создаётся, length = " << length << endl; }

Приведённый выше синтаксис эквивалентен следующему присваиванию в теле функции; оба дают точно такой же вывод:

Line::Line(double len) { length = len; // Присваиваем параметр len переменной-члену length cout << "Объект создаётся, length = " << length << endl; }

Разница между двумя подходами состоит в том, что список инициализации завершает инициализацию переменных-членов до входа в тело функции,перед этим, тогда как присваивание внутри тела функции сначала создаёт по умолчанию, а затем присваивает, что является одним лишним шагом. Дляconstдля const-членов, ссылочных членов и объектных членов без конструктора по умолчанию список инициализации являетсяединственнымспособом инициализации.

Предположим, есть класс C с несколькими полями X, Y, Z и т. д., которые нужно инициализировать; просто разделите разные поля запятыми, как показано ниже:

C::C(double a, double b, double c) : X(a), Y(b), Z(c) { // Остальная логика инициализации (если есть) }

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

Деструктор класса

ДеструкторклассаДеструктор — это особая функция-член класса. В конце времени жизни объекта (когда он выходит из области видимости илиdeleteудаляется), он автоматически выполняется, чтобы освободить ресурсы, занятые объектом (такие как динамическая память, файловые дескрипторы и т. д.).

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

Следующий пример помогает лучше понять концепцию деструкторов:

Пример

#include <iostream> using namespace std; class Line { public: Строка(); // Объявление конструктора ~Строка(); // Объявление деструктора void setLength(double len); double getLength() const; private: double length; }; // Определение конструктора Line::Line() { cout << "Объект создаётся" << endl; length = 0.0; } // Определение деструктора Line::~Line() { cout << "Объект удаляется" << endl; // Если есть динамически выделенные ресурсы, освободите их здесь, например, delete[] data; } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // Главная функция программы int main() { Line line; // Когда программа завершается, деструктор вызывается автоматически // Установить длину line.setLength(6.0); cout << "Длина линии : " << line.getLength() << endl; return 0; }

Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:

Object is being created
Length of line : 6
Object is being deleted

Классы & объекты C++

Другие расширения