HTML [44] |
Visual C++ и MFC [21] |
c++ [78] |
php [19] |
Javascript [15] |
C# [51] |
загрузки [0] |
XNA
[10]
создание игр с помощью xna
|
Главная » Статьи » 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, но после уничтожения всех других объектов.
| |||
Просмотров: 10994 | Рейтинг: 5.0/4 |
Всего комментариев: 0 | |