Среда, 08.01.2025, 20:30
Главная Регистрация RSS поиск
Приветствую Вас, Гость
Меню сайта
Категории раздела
HTML [44]
Visual C++ и MFC [21]
c++ [78]
php [19]
Javascript [15]
C# [51]
загрузки [0]
XNA [10]
создание игр с помощью xna
Наш опрос
Каким языком программирования вы увлекаетесь
Всего ответов: 2420
Статистика

Онлайн всего: 2
Гостей: 2
Пользователей: 0
Реклама
Главная » Статьи » c++

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

Инициализация объектов класса: конструкторы

Часто во время создания объекта его элементам необходимо присвоить начальные значения. Сделать это непосредственно в определении класса нельзя, например, следующее описание приведет к ошибке компиляции:

class my_Time {
public:
 int hours = 0; // ошибка
 int minutes = 0; // ошибка
};

С другой стороны, если не присвоить начальные значения элементам hours (часы) и minutes (минуты), то может возникнуть ситуация, когда при выводе на экран времени, получим, например, следущее:

 -858993460:-834562789

Избежать подобную ситуацию можно, например, написав функцию, которая будет присваивать нулевые значения элементам hours и minutes, и вызывать эту функцию каждый раз сразу после объявления объекта. Но в языке С++ есть такой механизм как конструкторы. Конструктор (construct - создавать) - это специальная функция-член класса с тем же именем, что и класс. Таким образом, конструктор - это функция, но в соответствии с синтаксисом языка С++ для конструктора не определяется тип возвращаемого значения. Нельзя указывать даже void (конструктор никогда не возвращает значение).

Пример конструктора:
 my_Time() { hours = 0; minutes = 0; }

Тогда описание класса my_Time будет следующее:

class my_Time {
public:
 // данные-члены класса
 int hours; 
 int minutes;

 // конструктор имеет то же имя, что и класс
 my_Time() { hours = 0; minutes = 0; }
};

Конструктор автоматически вызывается при создании объекта (создании экземпляра класса), т.е не нужно специально вызывать конструктор - это сделает компилятор. Например, определим объект time1 типа my_Time,

my_Time time1; 
здесь при создании объекта автоматически вызывается конструктор my_Time();. Таким образом, проинициализировать объект можно в конструкторе.
Основное назначение конструкторов - инициализация объектов.

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

С помощью параметров конструктору можно передать любые данные, необходимые для инициализации объектов класса.

Рассмотрим небольшой пример. Опишем класс Точка (Point), который будет содержать координаты точки в двумерной системе координат, функцию вывода координат точки на экран, функцию смещения точки относительно нового центра координат. Затем, просто создадим одну точку и выведем ее координаты на экран. После пересчитаем координаты точки относительно нового центра и снова выведем данные на экран.

#include <iostream.h>

// описание класса Point
class Point {
 int x, y; // координаты точки, по умолчанию имеют 
 // уровень доступа private
public:
 // конструктор присваивает переменным класса x и y начальные 
 // значения соответственно x0 и y0
 Point(int x0, int y0)
 {
 x = x0;
 y = y0;
 }
 
 // функция вывода координат точки на экран
 void ShowPoint()
 {
 cout << "\nx = " << x;
 cout << "\ny = " << y;
 }
 
 // функция пересчета координат точки относительно нового центра 
 // с координатами в точке (x0, y0)
 void OffsetXY(int x0, int y0)
 {
 x -= x0;
 y -= y0;
 }
};

void main()
{
 Point A(1,3); // создаем точку А (объект типа Point) 
 // с координатами x = 1, y = 3 (вызывается конструктор Point(1, 3)
 A.ShowPoint(); // выводим координаты точки А на экран
 A.OffsetXY(2,2); // переносим центр координат в точку (2,2)
 A.ShowPoint(); // показываем новые координаты точки А
}

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

 Point A(1,3);
Такое определение создает экземпляр A класса Point, вызывая конструктор класса с параметрами (1,3).

Использование конструкторов с аргументами по умолчанию

Конструктор без параметров называют конструктором по умолчанию. Такой конструктор обычно присваивает переменным-членам класса наиболее часто используемые значения. Например, в описанном выше примере класса my_Time используется конструктор по умолчанию.

 my_Time() { hours = 0; minutes = 0; }
В нем переменным hours и minutes присваиваются нулевые значения. Таким образом, после создания экземляра объекта типа my_Time, он будет содержать вполне допустимые значения, а не "мусор".

Для каждого класса может существовать только один конструктор по умолчанию.

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

Если класс имеет конструктор по умолчанию (определенный программистом или созданный компилятором), можно определить объект класса без передачи параметров, например:

 my_Time time1;
Если параметры не передаются конструктору, в определении объекта не нужно включать пустые круглые скобки.

Следующая команда, например, не создает объект типа my_Time, с вызовом конструктора по умолчанию,

 my_Time times ();
а является определением функции times, которая не принимает параметров и возвращает объект типа my_Time.

Давайте добавим к нашему классу конструктор по умолчанию, который будет инициализировать данные-члены класса нулевыми значениями. Тогда программа примет вид:

#include <iostream.h>

// описание класса Point
class Point {
 int x, y; // координаты точки, по умолчанию имеют 
 // уровень доступа private
public:
 // конструктор по умолчанию инициализирует данные-члены класса нулевыми значениями
 Point()
 {
 x = 0;
 y = 0;
 }

 // конструктор присваивает переменным класса x и y начальные значения 
 // соответственно x0 и y0
 Point(int x0, int y0)
 {
 x = x0;
 y = y0;
 }
 
 // функция вывода координат точки на экран
 void ShowPoint()
 {
 cout << "\nx = " << x;
 cout << "\ny = " << y;
 }
 
 // функция пересчета координат точки относительно нового центра 
 // с координатами в точке (x0, y0)
 void OffsetXY(int x0, int y0)
 {
 x -= x0;
 y -= y0;
 }
};

void main()
{
 Point A(1,3); // создаем точку А (объект типа Point) 
 // с координатами x = 1, y = 3 (вызывается конструктор Point(int, int))

 cout << "\nPoint A is \n";
 A.ShowPoint(); // выводим координаты точки А на экран
 A.OffsetXY(2,2); // переносим центр координат в точку (2,2)
 A.ShowPoint(); // показываем новые координаты точки А

 Point B; // создаем точку В (вызывается конструктор по умолчанию Point())
 cout << "\nPoint B is \n";
 B.ShowPoint(); // выводим координаты точки В на экран
}

Как видно из примера, класс может иметь несколько конструкторов.

Использование деструкторов

Деструктор решает задачу, обратную задаче конструктора. Деструктор (destruct - разрушать) - это специальная функция-член класса. Имя деструктора состоит из символа тильда (~) и имени класса.

Пример деструктора:
 ~my_Time() 
 { // тело деструктора
 }

Деструктор класса вызывается при уничтожении объекта - например, когда объект выходит из области видимости. Деструктор может выполнять любые задачи, необходимые для удаления объекта. Например, если в конструкторе была динамически выделена область памяти для хранения массива строк, то деструктор должен освободить эту память непосредственно перед удалением экземпляра класса.

Деструктор не принимает никаких параметров и не возвращает никаких значений. Класс может иметь только один деструктор.

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

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

Когда вызываются конструкторы и деструкторы.

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

Если объект определен глобально (т.е. вне любой функции), то конструктор вызывается в самом начале программы до вызова функции main), деструктор - по окончании программы.

Если объект определен локально (т.е. внутри функции), то конструктор вызывается, когда выполнение программы достигает определения объекта, деструктор - при выходе из блока, в котором определен объект (т.е. когда объект выходит из области видимости).

Если объект определен локально с использованием спецификатора static, конструктор вызывается сразу же, как только процесс выполнения впервые достигает места, где объект был объявлен, деструктор - в конце программы.

Пример Программы показывает последовательность, в которой вызываются конструкторы и деструкторы объектов типа CreateAndDestroy в разных областях видимости. Объект first является глобальным объектом, его конструктор вызывается, как только программа начинает выполнение, а его деструктор вызывается по завершении программы, после того, как все другие объекты уничтожены.

В функции main объявлено три объекта. Объекты second и fourth являются локальными объектами, а объект third объявлен с классом памяти static. Конструкторы каждого из этих объектов вызываются, когда процесс выполнения достигает места, где объекты были объявлены. Деструкторы объектов fourth и second вызываются в соответствующем порядке, когда заканчивается main. Поскольку объект third - статический, то он существует до завершения программы. Деструктор объекта third вызывается раньше деструктора для first, но после уничтожения всех других объектов.

Функция create объявляет три объекта - локальные объекты fifth и seventh и статический локальный объект sixth. Деструкторы для объектов seventh и fifth вызываются в соответствующем порядке по окончании create. Поскольку sixth - статический объект, он существует до завершения программы. Деструктор для sixth вызывается раньше деструктора для third и first, но после уничтожения всех других объектов.

Программа
/* Демонстрация последовательности, в которой вызываются 
конструкторы и деструкторы. */

#include<iostream.h>

// описание класса CreateAndDestroy
class CreateAndDestroy
{
public: 
 CreateAndDestroy(int value) // конструктор 
 {
 data = value;
 cout << " Object " << data << " constructor";
 }

 ~CreateAndDestroy() // деструктор
 {
 cout << " Object " << data << " destructor" << endl;
 }
private:
 int data;
};


CreateAndDestroy first(1); // глобальный объект

void create(void); //прототип функции

void main ()
{
 cout << "\t(global object) " << endl;
 
 CreateAndDestroy second(2); // локальный объект
 cout << "\t(local auto object in main) " << endl;

 static CreateAndDestroy third(3); // статический объект
 cout << "\t(local static object in main) " << endl;

 create(); // вызов функции создания объектов

 CreateAndDestroy fourth(4); // локальный объект
 cout << "\t(local auto object in main) " << endl;
}

// Функция создания объектов
void create(void)
{
 CreateAndDestroy fifth(5); // локальный объект
 cout << "\t(local auto object in create) " << endl;

 static CreateAndDestroy sixth(6); // статический объект
 cout << "\t(local static object in create) " << endl;

 CreateAndDestroy seventh(7); // локальный объект
 cout << "\t(local auto object in create) " << endl;
}
Результаты выполнения программы
Object 1 constructor (global object)
Object 2 constructor (local auto object in main)
Object 3 constructor (local static object in main)
Object 5 constructor (local auto object in create)
Object 6 constructor (local static object in create)
Object 7 constructor (local auto object in create)
Object 7 destructor 
Object 5 destructor 
Object 4 constructor (local auto object in main)
Object 4 destructor 
Object 2 destructor 
Object 6 destructor 
Object 3 destructor 
Object 1 destructor 
Категория: c++ | Добавил: slava (30.05.2011)
Просмотров: 10994 | Рейтинг: 5.0/4
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]