logo
шпоры по ООП

63.Использование конструкторов и деструкторов в роли «вступления» и «заключения».

Использование конструкторов и деструкторов в роли «вступления» и «заключения».

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

struct Student{

int semhours;//public по умолчанию

char subj; }

Student s={0,”c” };//объявление и инициализация

При использовании класса приложение не имеет доступа к его защищенным элементам, поэтому для класса подобную инициализацию выполнить нельзя. Для этой цели используются специальная функция-член класса, инициализирующая экземпляр класса и указанные переменные при создании объекта. Подобная функция вызывается всегда при создании объекта класса. Это и есть конструктор – функция-член класса, которая имеет то же имя, что и класс. Конструктор может быть подставляемой (inline) и неподставляемой функциями. Рассмотрим пример:

#include<iostream.h> // пример 22

class Student{

int semhours;

char subj;

public:

Student() //inline-конструктор 1 без параметров

{semhours=0; subj='A';}

Student(int, char); //объявление конструктора 2 с параметрами

};

Student::Student(int hours,char g)//конструктор 2

{semhours=hours; subj=g;}

int main(){

student s(100,'A'); //конструктор 2

student s1[5]; //конструктор1 вызывается 5 раз

return 0;

}

Там, где находятся объявления s и s1, компилятор помещает вызов соответствующего конструктора Student().

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

От нас скрыты особенности реализации деструкторов. Не существует даже средства стандартной эффективной проверки результата выполнения деструктора: в некоторых реализациях можно обратиться к функциям-членам объекта даже после уничтожения этого объекта деструктором.

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

Пример 2.

class Stack {

char *stck; // содержит стек

int tos; // индекс вершины стека

public:

Stack(); //конструктор

~Stack(){delete [] stck;}//деструктор

void push(char ch); // помещает в стек символ

char pop(); // выталкивает из стека символ

};

// инициализация стека

Stack::Stack(){

stck=new char[SIZE];//динамический массив

tos=0;

cout << "работа конструктора … \n";

}

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

Деструктор ~Stack() выполняет действия необходимые для корректного завершения работы с объектом, а именно, в деструкторе может освобождаться динамически выделенная память, закрываться соединения с файлами, и др. Он не имеет аргументов. Именем деструктора является имя класса, перед которым стоит знак “~” – тильда.