Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






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

Лекція 6

 

План

1. Поняття конструкторів та деструкторів.

  1. Формат конструктора та деструктора в С++.
  2. Типи конструкторів.
  3. Вказівник this

 

1. Поняття конструкторів та деструкторів.

 

Конструкторы и деструкторы - это специальные методы класса. Это надо понять в первую очередь. Разумеется, эти методы обладают целым рядом особенностей (именно по этому они и выделены в специальную группу). Сейчас мы об этих особенностях и поговорим.

Первое. В отличие от других методов они должны называться особым образом. Если обычные методы могут называться как угодно, то имя констуктора должно совпадать с именем класса, а имя деструктора - с именем класса с приписанной в начале тильдой. Например, если класс называется CRect, то конструктор этого класса обязан называться тоже CRect, а деструктор - ~CRect.

Второе. В отличии от других методов конструктор и деструктор вызываются сами (а другие методы мы вызываем явным образом). Конструктор вызывается в момент создания экземпляра класса, а деструктор - в момент уничтожения. Т. е. их не надо вызывать явным образом - они вызываются сами. Именно поэтому конструкторы обычно используются для задания некоторых начальных значений для переменных класса, а деструкторы - для освобождения памяти (в случае если у вас есть внутри класса переменные-указатели).

Третье. Ни конструктор, ни деструктор не возвращают никакого значения (даже типа void). Это означает, в частности, что при обяъвлении конструтора и деструктора в классе мы перед ними не пишем ни какой тип.

Четвертое. В классе может быть несколько конструкторов (и они должны различаться параметрами), и только один деструктор (у него параметров вообще быть не может).

Прежде всего хочется указать на одну из самых распространённых ошибок начинающих: они считают, что конструктор выделяет память для объекта, а деструктор - освобождает. Это неверно! Процесс выделения памяти для объекта следующий:

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

Статический объект, попавший в исполняемый файл. Время жизни начинается до входа в процедуру main и заканчивается после выхода из процедуры main

Статический объект, попавший в динамическую библиотеку. Время жизни начинается с момента загрузки динамической библиотеки и заканчивается в момент выгрузки динамической библиотеки.

Динамический объект. Время жизни начинается в момент явного выделения памяти для объекта и заканчивается в момент явного освобождения памяти. Если память явным образом не освобождается, то данная память так и остаётся использованной и будет высвобождена средствами операционной системы.

А конструктор только инициализирует объект (т.е. задаёт объекту некоторое начальное значение). Очень важно это понимать. Непонимание обычно растёт из того, что эти два этапа с точки зрения языка обычно выглядят в виде одного оператора. Компилятор обеспечивает механизм, при котором в процессе создания объекта выделяется память под объект и вызывается метод-конструктор. Но эти две вещи не обязательно выполняются подряд одна за другой. Аналогично в процессе удаления объект вызывается метод-деструктор и затем происходит высвобождение памяти.

 

2.Формат конструктора та деструктора в С++.

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

class T

{

private:

int x, y;

public:

T (int _x, int _y) { x = _x; y = _y; }

/* Смысла в этом деструкторе нет, но пишу его в таком виде, чтобы он был не пустой */

~T () { x = 0; y = 0; }

}

void

func (void)

{

T a(10, 11), b(20, 21);

 

/* тело процедуры */

}

 

По синтаксису языка конструкторы и деструкторы выглядят как процедуры. Техническая их реализация (т.е. реализация в виде кода) ничем не отличается от реализации обычной процедуры. Однако с точки зрения языка Си++ конструктор функцией НЕ является, а потому нельзя вызывать конструктор " ручками" и нельзя брать адрес на конструктор. Логика такого поведения следующая: конструктор является механизмом инициализации объекта, а инициализация является составной частью процесса порождения объекта. И, таким образом, конструктор может вызываться только непосредственно в момент рождения объекта.

С деструкторами логика ровно такая же, однако по языку деструктор можно вызывать " ручками" и брать на него адрес. Такое поведени обусловлено тем, что в языке Си++ существует оператор new, который выделяет память не абы где, а использует ту память, которую ему навязал программист

Пример №2

#include < iostream>

 

class T

{

int x;

public:

T() { std:: cout < < " constr\n"; }

~T() { std:: cout < < " destr\n"; }

};

 

int main (void)

{

char *buf = new char[sizeof(T)];

T *t = new(buf) T;

 

t-> ~T();

}

Пример №3:

class mod_int {

public:

mod_int(int i); //объявление контруктора void assign(int i) { v = i % modulus; } void print () const { cout < < v < < '\t'; } const static int modulus = 60;

private: int v;

};

//определение конструктора mod_int:: mod_int(int i) { v = i % modulus; } const int mod_int:: modulus;

Целая переменная v ограничена значениями 0, 1, 2.....modulus - 1. Ответственность за выполнение этого ограничения лежит на программисте; все функции-члены долж­ны вести себя, соблюдая это правило.

Функция-член mod_int:: mod_int (int) является конструктором. Она не имеет возвращаемого типа. Она вызывается, когда объявляются объекты THnamod_int. Это функция одного аргумента. При вызове конструктор ожидает выражение, преобразуемое по умолчанию к его целому параметру. Затем он создает и инициализует объявленную переменную.

Вот некоторые примеры объявлений с использованием данного типа:

mod_int а(0); //a.v = О mod_int Ь(61); //a.v = 1

mod_int а; //недопустимо, т.к. нет списка параметров

Поскольку у этого класса лишь один конструктор со списком аргументов int, объявление mod_int должно получать целое выражение, передаваемое в качестве инициа-лизующего значения. Заметьте, что не допуская объявления переменной типа mod_int без выражения-инициализатора, мы тем самым предотвращаем ошибки на этапе выполнения из-за неинициализованных переменных.

 

3.Типи конструкторів

<== предыдущая лекция | следующая лекция ==>
При поступлении (выдаче) денежных средств в помещении кассы имеют право находиться только лица, непосредственно участвующие в данной хозяйственной операции. | Адрес: г. Ижевск, ул. М.Горького, 73.




© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.