Конструктор – это функция-член класса, которая автоматически вызывается при объявлении объекта этого класса. Конструктор предназначен для инициализации всех или только некоторых членов-данных объекта. Конструкторы определяются точно так же, как и любые другие функции, за исключением двух моментов:
Ø Конструктор должен иметь то же имя, что и сам класс.
Ø Конструктор не может возвращать значение. Более того, в прототипе или заголовке определения конструктора никакой тип (даже void) не указывается.
Конструктор, объявляемый без аргументов, называется конструктором по умолчанию (default constructor).
Конструктор при инициализации объектов может вызываться либо неявно, что делается чаще, либо явно, используя имя конструктора:
. . . . . . . . . . . . . . . . . .
Date today(15); //Неявный вызов конструктора
Date yesterday = Date(14, 07); //Явный вызов конструктора
. . . . . . . . . . . . . . . . . .
Одной из важнейших форм перегружаемого конструктора является конструктор копирования (copy constructor), который служит для получения точных копий уже существующего объекта. В частности конструктор копирования вызывается, когда объект передается функции по значению, при построении временного объекта как возвращаемого значения функции, а также при использовании объекта для инициализации другого объекта.
Любой конструктор копирования имеет следующую общую форму:
Имя_класса(const имя_класса &obj);
Параметры конструктору можно передать с помощью списка инициализации членов. Этот список следует сразу за списком формальных параметров и отделяется от него двоеточием. Отдельный элемент списка представляет собой имя инициализируемого члена-данного, за которым в круглых скобках задается инициализирующее выражение.
Если член-данное является ссылкой или имеет спецификацию const, то его можно инициализировать только с помощью списка инициализации.
Для любого создаваемого класса рекомендуется создавать три конструктора: основной конструктор, конструктор по умолчанию и конструктор копирования.
Деструкторы (destructor) - из той же категории, что и конструкторы. Они используются для выполнения определенных операций при удалении объекта. Деструктор вызывается автоматически при выходе объекта из области видимости. Деструктор имеет имя, всегда совпадающее с именем класса, но предваряется операцией дополнение (~).
Деструктор в С++ имеет следующие особенности и подчиняется следующим правилам:
Ø В деструкторе не определяется тип возвращаемого значения, даже тип void;
Ø Деструктор не должен иметь параметров;
Каждый объект данного класса хранит свою копию членов-данных, но для всех объектов вызывается один и тот же вариант функции-члена. Для того, чтобы не путать такие объекты, у каждой функции-члена имеется неявный скрытый указатель this. Указатель this – это предопределенный компилятором указатель, который всегда указывает на объект класса, для которого вызывается функция-член этого класса. Он объявляется компилятором следующим образом:
Имя_класса*const this;
Поскольку this – это ключевое слово, то его нельзя объявить явно, но явно пользоваться им можно. Изменить значение этого указателя также нельзя, поскольку он объявлен как константный указатель.
//функция, которая считывает системное время в текущий объект:
void TodayTime()
{
SYSTEMTIME t; /* структура типа SYSTEMTIME определена в заголовочном файле <windows.h> */
GetLocalTime(&t);
/* считываем системное время с помощью функции, объявленной в <windows.h>, при этом заполняется структура t */
/* устанавливаем текущее время, используя элементы структуры t: */
hour = t.wHour;
min = t.wMinute;
sec = t.wSecond;
}
/* функция, которая устанавливает новое системное время, используя элементы данных текущего объекта: */
void SetTime()
{
SYSTEMTIME t; /*структура типа SYSTEMTIME, которая требуется функции SetLocalTime(), устанавливающей системное время: */
/* заполняем структуру t, используя элементы данных текущего объекта и местное время: */
GetLocalTime(&t);
t.wHour = hour;
t.wMinute = min;
t.wSecond = sec; // сотые доли секунды
SetLocalTime(&t); // устанавливаем новое системное ms-help: //MS.VSCC.v80/MS.MSDN.v80/MS.WIN32COM.v10.en/sysinfo/base/setlocaltime.htm
}
};
// пример программы, использующей класс CTime:
int main()
{
//Настройки шрифтов и региональных стандартов:
if(SetConsoleCP(1251)==0)
//проверка правильности установки кодировки символов для ввода
{
cerr<<"Fialed to set codepage!"<<endl;
/* если не удалось установить кодовую страницу, вывод сообщения об ошибке */
}
if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода
{
cerr<<"Failed to set OUTPUT page!"<<endl;
}
CTime tm1, tm2;
tm1.Input();
cout << "Задано время: ";
tm1.Output();
tm2.TodayTime();
cout << "Системное время: ";
tm2.Output();
// Корректируем количество минут в системном времени:
WORD mn;
cout << "Задайте минуты ";
cin >> mn;
tm2.SetMin(mn);
tm2.SetTime();
tm2.TodayTime();
cout << "Новое системное время: ";
tm2.Output();
_getch();
return 0;
}
Пример 3: Класс, описывающий двумерный массив.
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <iomanip>
using namespace std;
class DArray
{
int** a; // Указатель на двумерный массив(матрицу)
int x,y; // размеры массива
public:
//конструкторы:
DArray(); // по умолчанию
DArray(int**,int,int); // основной
DArray(const DArray&); // копирования
/*деструктор (в этом классе явное описание деструктора обязательно, поскольку он должен освободить память, захваченную конструктором): */
~DArray();
/* функция, которая заполняет массив данными из массива-источника: */
void Set_array(int**, int, int);
// функция, которая возвращает указатель на массив:
int** Get_array();
// функции ввода-вывода:
void input();
void output();
};
// Определение функций:
/* Конструктор по умолчанию (создает массив 2*2, заполненный нулями): */
DArray::DArray()
{
x=2; y=2;
// Выделяем память под массив:
a = new int* [x];
for (int i=0; i<x; i++)
a[i]=new int [y];
// заполняем массив нулями:
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
a[i][j]=0;
}
// Основной конструктор (создает массив, заполненный данными из массива-источника):
DArray::DArray(int** aa,int xx,int yy)
{
/* Конструктор использует функцию Set_array(). Поскольку эта функция освобождает память, ранее выделенную под массив, а при вызове конструктора еще текущий массив не определен, показываем это, задавая размеры, равные 0. */
x = y = 0;
Set_array(aa, xx, yy);
}
// Деструктор:
DArray::~DArray()
{
// Освобождаем память, выделенную под элементы массива:
for (int i=0; i<x; i++)
delete []a[i];
// Освобождаем память, выделенную под указатели:
delete []a;
}
void DArray::Set_array(int** aa, int xx, int yy)
{
// Если объект уже существует, удаляем его:
if (x && y)
this->~DArray();
/* Обратите внимание на то, как можно явно вызвать деструктор (хотя это не рекомендуется) */
// Создаем массив таких же размеров, что и массив-источник:
x=xx; y=yy;
a = new int* [x];
for (int i=0; i<x; i++)
a[i]=new int [y];
// Заполняем массив данными из массива-источника:
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
a[i][j]=aa[i][j];
}
// Конструктор копирования:
DArray::DArray(const DArray& obj)
{
//Создаем копию объекта obj:
x=obj.x; y=obj.y;
a = new int* [x];
for (int i=0; i<x; i++)
a[i]=new int [y];
// Заполняем созданную копию данными из массива obj:
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
a[i][j]=obj.a[i][j];
}
// Функция, возвращающая указатель на массив:
int** DArray::Get_array()
{
return a;
}
// функция ввода:
void DArray::input()
{
// Удаляем ранее созданный объект:
if (x && y)
this->~DArray();
do
{
cout << "Задайте количество строк матрицы: ";
cin >> x;
cout << "Задайте количество столбцов матрицы: ";
cin >> y;
} while(x<0||y<0);
// Размещаем массив в памяти:
a = new int* [x];
for (int i=0; i<x; i++)
a[i]=new int [y];
// Считываем элементы с клавиатуры:
for (int i=0; i<x; i++)
{
for (int j=0; j<y; j++)
{
cout << "Задайте значение [" << i << ", " << j <<"] элемента:";
cin >> a[i][j];
}
cout << endl;
}
}
// Функция вывода:
void DArray::output()
{
for (int i=0; i<x; i++)
{
for (int j=0; j<y; j++)
{
cout << setw(4) << a[i][j];
}
cout << endl;
}
}
// Пример программы, использующей класс Darray:
int main()
{
//Настройки шрифтов и региональных стандартов:
if(SetConsoleCP(1251)==0)
//проверка правильности установки кодировки символов для ввода
{
cerr<<"Fialed to set codepage!"<<endl;
}
if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода
{
cerr<<"Failed to set OUTPUT page!"<<endl;
}
DArray A, B; //вызывается конструктор по умолчанию (2 раза)