При создании объектов одной из наиболее широко используемых операций которую вы будете выполнять в ваших программах, является инициализация элементов данных объекта. Как вы узнали из урока 22, единственным способом, с помощью которого вы можете обратиться к частным элементам данных, является использование функций класса. Чтобы упростить процесс инициализации элементов данных класса, C++ использует специальную функцию, называемую конструктором, которая запускается для каждого создаваемого вами объекта. Подобным образом C++ обеспечивает функцию, называемую деструктором, которая запускается при уничтожении объекта. В данном уроке конструктор и деструктор рассматриваются более подробно. К концу этого урока вы освоите следующие основные концепции:

  • Конструктор представляет собой метод класса, который облегчает вашим программам инициализацию элементов данных класса.
  • Конструктор имеет такое же имя, как и класс.
  • Конструктор не имеет возвращаемого значения.
  • Каждый раз, когда ваша программа создает переменную класса, C++ вызывает конструктор класса, если конструктор существует.
  • Многие объекты могут распределять память для хранения информации; когда вы уничтожаете такой объект, C++ будет вызывать специальный деструктор, который может освобождать эту память, очищая ее после объекта.
  • Деструктор имеет такое же имя, как и класс, за исключением того, что вы должны предварять его имя символом тильды (~).
  • Деструктор не имеет возвращаемого значения.

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

СОЗДАНИЕ ПРОСТОГО КОНСТРУКТОРА

Конструктор представляет собой метод класса, который имеет такое же имя, как и класс. Например, если вы используете класс с именемemployee, конструктор также будет иметь имяemployee. Подобно этому, для класса с именем dogs конструктор будет иметь имяdogs. Если ваша программа определяет конструктор, C++ будет автоматически вызывать его каждый раз, когда вы создаете объект. Следующая программа CONSTRUC.CPP создает класс с именемemployee. Программа также определяет конструктор с именемemployee который присваивает начальные значения объекту. Однако конструктор не возвращает никакого значения, несмотря на то, что он не объявляется как void. Вместо этого вы просто не указываете тип возвращаемого значения:

class employee

{
public:
   employee(char *, long, float); //Конструктор
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
};

В вашей программе вы просто определяете конструктор так же, как любой другой метод класса:

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0)
   employee::salary = salary;
   else // Недопустимый оклад
   employee::salary = 0.0;
}

Как видите, конструктор не возвращает значение вызвавшей функции. Для него также не используется типvoid. В данном случае конструктор использует оператор глобального разрешения и имя класса перед именем каждого элемента, как уже обсуждалось в уроке 23. Ниже приведена реализация программы CONSTRUC.CPP:

#include  

#include

class employee

{
public:
   employee(char *, long, float);
   void show_employee(void);
   int change_salary(float) ;
   long get_id(void);
private:
   char name [64] ;
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0)
      employee::salary = salary;
   else // Недопустимый оклад
      employee::salary = 0.0;
}

void employee::show_employee(void)

{
   cout << "Служащий:" << name << endl;
   cout << "Номер служащего: "<< employee_id << endl;
   cout << "Оклад:" << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   worker.show_employee();
}

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

employee worker("Happy Jamsa", 101, 10101.0);

Если вашей программе потребуется создать несколько объектовemployee, вы можете инициализировать элементы каждого из них с помощью конструктора, как показано ниже:

employee worker("Happy Jamsa", 101, 10101.0);

employee secretary("John Doe", 57, 20000.0);

employee manager("Jane Doe", 1022, 30000.0);

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

Конструктор представляет собой специальную функцию, которую C++ автоматически вызывает каждый раз при создании объекта. Обычное назначение конструктора заключается в инициализации элементов данных объекта. Конструктор имеет такое же имя, как и класс. Например, класс с именемfile использует конструктор с именемfile. Вы определяете конструктор внутри своей программы так же, как и любой метод класса. Единственное различие заключается в том, что конструктор не имеет возвращаемого значения. Когда вы позже объявляете объект, вы можете передавать параметры конструктору, как показано ниже:

class_name object(valuel, value2, value3)

Конструкторы и параметры по умолчанию

Как вы уже знаете из урока 15, C++ позволяет указывать значения по умолчанию для параметров функции. Если пользователь не указывает каких-либо параметров, функция будет использовать значения по умолчанию. Конструктор не является исключением; ваша программа может указать для него значения по умолчанию так же, как и для любой другой функции. Например, следующий конструкторemployee использует по умолчанию значение оклада равным 10000.0, если программа не указывает оклад при создании объекта. Однако программа должна указать имя служащего и его номер:

employee::employee(char *name, long employee_id, float salary = 10000.00)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   if (salary < 50000.0)
      employee::salary = salary;
   else // Недопустимый оклад
      employee::salary = 0.0;
}

Перегрузка конструкторов

Как вы уже знаете из урока 13, C++ позволяет вашим программам перегружать определения функций, указывая альтернативные функции для других типов параметров. C++ позволяет вам также перегружать конструкторы. Следующая программа CONSOVER.CPP перегружает конструкторemployee. Первый конструктор требует, чтобы программа указывала имя служащего, номер служащего и оклад. Второй конструктор запрашивает пользователяввести требуемый оклад, если программа не указывает его:

employee::employee(char *name, long employee_id)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   do

   {
      cout << "Введите оклад для" << name << " меньше $50000: ";
      cin >> employee::salary;
   }
   while (salary >= 50000.0);
}

Внутри определения класса программа должна указать прототипы для обоих конструкторов, как показано ниже:

class employee

{
public:
   employee (char *, long, float);|___ Прототипы перегруженных
   employee(char *, long);          |функций
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
}

Ниже приведена реализация программы CONSOVER.CPP:

#include

#include

class employee

{
public:
   employee(char *, long, float);
   employee(char *, long);
   void show_employee(void);
   int change_salary(float) ;
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   if (salary < 50000.0) employee::salary = salary;
   else // Недопустимый оклад
      employee::salary = 0.0;
}

employee::employee(char *name, long employee_id)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   do

   {
    cout << "Введите оклад для" << name << " меньше $50000: ";
   cin >> employee::salary;
   }
   while (salary >= 50000.0);
}

void employee::show_employee(void)

{
   cout << "Служащий:" << name << endl;
   cout << "Номер служащего: "<< employee_id << endl;
   cout << "Оклад:" << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   employee manager("Jane Doe", 102);
   worker.show_employee();
   manager.sbow_employee();
}

Если вы откомпилируете и запустите эту программу, на вашем экране появится запрос ввести оклад для Jane Doe. Когда вы введете оклад, программа отобразит информацию об обоих служащих.

ПРЕДСТАВЛЕНИЕ О ДЕСТРУКТОРЕ

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

Каждая из созданных вами до сих пор программ создавала объекты в самом начале своего выполнения, просто объявляя их. При завершении программ C++ уничтожал объекты. Если вы определяете деструктор внутри своей программы, C++ будет автоматически вызывать деструктор для каждого объекта, когда программа завершается (т.е. когда объекты уничтожаются). Подобно конструктору, деструктор имеет такое же имя, как и класс объекта. Однако в случае деструктора вы предваряете его имя символом тильды (~), как показано ниже:

~class_name (void) //----------->указывает деструктор

{
// Операторы деструктора
}

В отличие от конструктора вы не можете передавать параметры деструктору. Следующая программа DESTRUCT.CPP определяет деструктор для классаemployee:

void employee::-employee(void)

{
   cout << "Уничтожение объекта для" << name << endl;
}

В данном случае деструктор просто выводит на ваш экран сообщение о том, что C++ уничтожает объект. Когда программа завершается, C++ автоматически вызывает деструктор для каждого объекта. Ниже приведена реализация программы DESTRUCT.CPP:

#include  

#include

class employee

{
public:
   employee(char *, long, float);
   ~employee(void);
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64] ;
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0) employee::salary = salary;
   else // Недопустимый оклад
   employee::salary в 0.0;
}

void employee::-employee(void)

{
   cout << "Уничтожение объекта для" << name << endl;
}

void employee::show_employee(void)

{
   cout << "Служащий:" << name << endl;
   cout << "Номер служащего: "<< employee_id << endl;
   cout << "Оклад:" << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   worker.show_employee();
}

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

С:> DESTRUCT

Служащий: Happy Jamsa

Номер служащего: 101

Оклад: 10101

Уничтожение объекта для Happy Jamsa

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

Деструкторы

Деструктор представляет собой функцию, которую C++ автоматически запускает, когда он или ваша программа уничтожает объект. Деструктор имеет такое же имя, как и класс объекта; однако вы предваряете имя деструктора символом тильды (~), например ~employee. Всвоей программе вы определяете деструктор точно так же, как и любой другой метод класса.

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Конструкторы и деструкторы представляют собой специальные функции класса, которые ваша программа автоматически вызывает при создании или уничтожении объекта. Большинство программ используют конструктор для инициализации элементов данных класса. Простые программы, создаваемые сейчас вами, вероятно, не потребуют использования деструктора. Из урока 24 вы узнаете, как перегружать операторы. Другими словами, вы можете переопределить символ плюс таким образом, что он будет добавлять содержимое одной строки к другой. Как вы уже знаете, тип (например,char, float и int) определяет набор значений, которые может хранить переменная, и набор операций, которые ваши программы могут выполнять над этой переменной. Когда вы определяете класс, вы по существу определяете тип. C++ позволяет вам указать, как ведут себя операторы с данным типом. До изучения урока 24 убедитесь, что освоили следующие основные концепции:

    1. Конструктор представляет собой специальную функцию, которую ваша программа автоматически вызывает каждый раз при создании объекта. Конструктор имеет такое же имя, как и класс объекта.
    2. Конструктор не имеет возвращаемого значения, но вы не указываете ему типvoid. Вместо этого вы просто не указываете возвращаемое значение вообще.
    3. Когда ваша программа создает объект, она может передать параметры конструктору во время объявления объекта.
    4. C++ позволяет вам перегружать конструкторы и разрешает использовать значения по умолчанию для параметров.
    5. Деструктор представляет собой специальную функцию, которую ваша программа вызывает автоматически каждый раз при уничтожении объекта. Деструктор имеет такое же имя, как и класс объекта, но его имя предваряется символом тильды (~).