- •1. Конструкторы и деструкторы
- •Конструкторы.
- •Int II; float ee; char cc;
- •Конструктор с параметрами или конструктор общего вида.
- •Конструктор с аргументами, задаваемыми по умолчанию.
- •Конструктор по умолчанию.
- •Конструктор копирования.
- •Определение конструктора копирования.
- •Деструкторы
- •Int main () {
- •Int main ( ) {
- •Void Print ( My obj )
- •Int main ( ) {
- •2. Указатели на поля данных и на методы класса.
- •Int main (){
- •3.Указатель this
- •Int X, y ; public:
- •Void print ( void)
- •Int main ()
- •Void que::add( ) {
- •Void que::print (void)
- •Int main( )
- •4. Перегрузка функций
- •Перегрузка конструкторов
Деструкторы
В языке С++ управление размещением объектов в памяти и их удаление из памяти, когда потребуется, полностью во власти программиста.
Объекты с нужными свойствами создаются с помощью конструкторов. Для выполнения действий, которые сопровождают удаление объектов, в каждом классе явно или неявно определяется специальный метод, называемый деструктором.
Деструктор - это компонентная функция класса (метод класса), которая автоматически выполняется, когда экземпляр класса уничтожается.
Деструктор вызывается либо при выходе объекта за пределы области действия объекта, либо при освобождении динамической памяти операцией delete, выделенной объекту при его создании с помощью операции new.
Назначение деструктора – выполнение действий, сопровождающих удаление объекта.
Наиболее важное это освобождение ресурсов, включенных в объект при его создании или при выполнении действий над объектом. Такими ресурсами могут быть участки памяти, динамически выделяемые для полей данных объекта, файлы, открытые при создании объекта и связанные с ним, и другие ресурсы.
Деструкторы могут быть нужны и при уничтожении объектов, не захвативших никаких ресурсов, например, для вывода завершающих фраз.
Класс может иметь несколько конструкторов, но деструктор может быть только один!!!
Формат определения деструктора в теле класса:
~имя_класса () {операторы_тела_деструктора};
Рассмотрим свойства деструкторов:
1) Между тильдой и именем класса нет пробелов.
2) У деструктора нет типа результата даже типа void и нет параметров даже типа void.
3) Деструктор выполняется неявно, автоматически, как только объект уничтожается. Его, как правило, никогда не вызывают, но можно вызывать и явно, если он определен в классе. Формат вызова конструктора:
имя_объекта. ~имя_класса ();
имя_указателя_на_объект_класса -> ~имя_класса ();
при этом объект будет продолжать существовать, только выполнятся те действия, которые записаны в теле деструктора.
Определим класс Men1, вариант класса Men, в котором присутствуют и конструктор, и деструктор.
В конструкторе кроме инициализирующих действий имеется еще вывод контрольной строки. Деструктор пусть также содержит вывод другой контрольной строки.
class Men1 {
char* name; int age;
public:
Men1 (char * n, int a) //конструктор
{ name = n; age = a; cout<<name <<" - begin "<<endl; }
void SetN (char*n) {name =n;} //метод для изменения поля name
void SetA (int a) { age = a;} //метод для изменения поля age
char* GetN ( ) { return name;} //возвращает значение name
int GetA { return age;} //возвращает значение age
~Men1 ( ) { cout<< name<<" - end"<<endl; } //деструктор
};
#include <iostream>
#include<conio.h>
using namespace std;
Int main () {
Men1 obj1 ("Петров", 34); //создаем статический объект
//Men1 m1; -не верно, в классе не объявлен конструктор без //параметров
Men1 * obj2 = new Men1 ("Иванов", 25); //динамический экземпляра //класса
cout<<obj1. GetN ( ) <<""<< obj1. GetA ( ) <<endl;
cout<< obj2->GetN ( ) <<""<< obj2->GetA ( ) <<endl;
_getch ();
return 0;}
Результат программы:
Петров -begin
Иванов -begin
Петров 34
Иванов 25
Петров -end
Итак, конструктор вызывался автоматически дважды при создании объектов - статического и динамической памяти.
Деструктор вызывался только один раз.
Для объекта obj2 деструктор не вызывался, так как память на объект выделялась "вручную" и также "вручную" должна быть освобождена, то есть система не констатирует факта уничтожение этого объекта при завершении программы.
Если перед _getch ()вставить строку:
delete (obj2);
то результат программы будет следующий:
Петров -begin
Иванов -begin
Петров 34
Иванов 25
Иванов -end
Петров - end
Причем при выводе, как первого, так и второго результата программа останавливается на вызове _getch (), выводятся все строки результатов, кроме последней строки, после нажатия клавиши выводится и последняя строка.
Продолжим рассмотрение конструктора копирования.
Рассмотрим использование конструктора копирования при копировании ресурсоемких объектов.
Конструктор копирования, предоставляемый компилятором по умолчанию, производит побитовое копирование полей, что может приводить к абсурдным результатам при копировании ресурсоемких объектов.
Рассмотрим программу, в которой вызов конструктора копирования по умолчанию приводит к "неправильному" копированию.
#include <iostream>
using namespace std;
class My { int* p;
public:
My (int a) //конструктор с параметром
{p= new int ; *p = a; }
int Get ( ) { return *p; } //возвращает значение по адресу указателя
~My() {delete(p);} //освобождает выделенную в конструкторе //память
};
void Print (My obj ) //функция вывода значения
{ cout<<'\n'<<obj.Get ( );}
