Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 25.11.2008 | Доступ: свободный | Студентов: 9592 / 1296 | Оценка: 4.06 / 3.66 | Длительность: 21:16:00
Лекция 15:

Классы. Создание новых типов данных

< Лекция 14 || Лекция 15: 12345 || Лекция 16 >

14.7. Конструкторы и деструкторы (резюме)

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

Создание объекта в соответствии с описанием данных в классе сводится к выделению ресурсов (как правило, речь идет об участке оперативной памяти) для хранения объекта и инициализации полей данных. К числу наиболее характерных методов инициализации участков памяти, которые не зависят от специфики задач, относятся три следующие процедуры:

  • очистка выделенной памяти (для числовых данных это соответствует записи нулей, для строковых данных – записи пустых строк);
  • заполнение выделенных полей константами, указанными при объявлении объекта;
  • копирование в поля нового объекта содержимого полей ранее объявленного объекта.

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

#include <iostream.h>
class B {
  int x;
public:
  B(){x=0; cout<<"Def_Constr_B "<<this<<endl;}
  B(int y){x=y; cout<<"Init_Constr_B "<<this<<endl;}
  B(const B &z){x=z.x; cout<<"Copy_Constr_B "<<this<<endl;}
  int get_x(){return x;}
  ~B(){cout<<"Destr B"<<this<<endl;}
};
void main()
{ B q1;         //обращение к конструктору по умолчанию
  B q2(2);      //обращение к конструктору инициализации 
  B q3(q2);     //прямое обращение к конструктору копирования
  B q4=q1;      //косвенное обращение к конструктору копирования
  cout<<"q1="<<q1.get_x()<<endl;
  cout<<"q2="<<q2.get_x()<<endl;
  cout<<"q3="<<q3.get_x()<<endl;
  cout<<"q4="<<q4.get_x()<<endl;
}
//=== Результат работы ===
Def_Constr_B  0012FF88   //конструктор по умолчанию, адрес q1.x
Init_Constr_B 0012FF84   //конструктор инициализации, адрес q2.x
Copy_Constr_B 0012FF80   //конструктор копирования, адрес q3.x
Copy_Constr_B 0012FF7C   //конструктор копирования, адрес q4.x
q1=0
q2=2
q3=2
q4=0
//Деструктор вызывается автоматически при выходе из блока
Destr B 0012FF7C       //уничтожение объекта q4
Destr B 0012FF80       //уничтожение объекта q3
Destr B 0012FF84       //уничтожение объекта q2
Destr B 0012FF88       //уничтожение объекта q1
14.3.

Если программист не включает в свой класс ни одного конструктора, то компилятор автоматически вписывает ему конструктор по умолчанию (в отличие от приведенного выше системный конструктор не чистит память) и конструктор копирования.

Специфика конструкторов заключается в следующем:

  • имя конструктора совпадает с именем класса;
  • перед именем конструктора отсутствует указание о типе возвращаемого значения;
  • как и любая другая функция, конструктор может иметь список параметров, передаваемых ему при объявлении объекта. В заголовке конструктора могут присутствовать параметры по умолчанию. У стандартного конструктора по умолчанию список параметров пуст;
  • программист имеет право написать столько конструкторов, сколько он считает нужным. Но как только он включил в описание класса тело хотя бы одного конструктора, компилятор никаких своих конструкторов добавлять не будет.

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

Пример нестандартного конструктора по умолчанию, который пришлось написать нам самим, мы видели в классе Rational – с нулевым знаменателем работать было бы нельзя.

В отличие от конструкторов, создающих объекты, деструктор их уничтожает, освобождая ресурсы, выделенные для хранения объекта. Деструктор у класса может быть только один. Если программист не напишет свой деструктор, который производит дополнительные нестандартные действия, то компилятор подключит системный деструктор. Имя деструктора начинается с "тильды", которая предшествует имени класса. Параметров у деструктора нет:

Rational v1;       //объявление с помощью конструктора по умолчанию
  Rational v2(1,2);  //использование конструктора инициализации
  Rational v3(v2);   //использование конструктора копирования
  ~Rational();       //деструктор

Явно к деструктору обращаться не приходится, т.к. он вызывается автоматически при выходе из блока программы, в котором был создан объект.

Иногда деструктор класса приходится писать. Необходимость в этом возникает в тех случаях, когда деструктор должен выполнить некоторые нестандартные действия. Например, если в классе создается динамический массив, то для его уничтожения приходится разрушать каждый элемент массива:

class array {
  int size;
  char *p;
public:
  array(int dim);              //конструктор создания динамического массива
  ~array(){ delete [] p; }     //деструктор разрушения массива
.........................
};
array::array(int dim)   //тело конструктора
{ p=new char[dim];      //запрос памяти под динамический массив
  if(!p)                //если память не выделена
    { cout<<"Allocation error"; exit(1); }
  size=dim;
}
< Лекция 14 || Лекция 15: 12345 || Лекция 16 >
Alexey Ku
Alexey Ku

Попробуйте часть кода до слова main заменить на 

#include "stdafx.h" //1

#include <iostream> //2
#include <conio.h>

using namespace std; //3

Александр Талеев
Александр Талеев

#include <iostream.h>
#include <conio.h>
int main(void)
{
int a,b,max;
cout << "a=5";
cin >> a;
cout <<"b=3";
cin >> b;
if(a>b) max=a;
else max=b;
cout <<" max="<<max;
getch();
return 0;
}

при запуске в visual express выдает ошибки 

Ошибка    1    error C1083: Не удается открыть файл включение: iostream.h: No such file or directory    c:\users\саня\documents\visual studio 2012\projects\проект3\проект3\исходный код.cpp    1    1    Проект3

    2    IntelliSense: не удается открыть источник файл "iostream.h"    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    1    1    Проект3

    3    IntelliSense: идентификатор "cout" не определен    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    6    1    Проект3

    4    IntelliSense: идентификатор "cin" не определен    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    7    1    Проект3

при создании файла я выбрал пустой проект. Может нужно было выбрать консольное приложение?