Конструктор включается в состав класса в разделе public:
class Printer
{
…
public:
Printer(); //Конструктор
…
};
Конструктор выделяет память под объект, достаточную для размещения всего объекта, и инициализирует переменные состояния объекта:
Printer :: Printer()
{
strcpy(model,"Canon_BJC250");
year=2000;
status=0;
}
Тогда программа, создающая объект и отображающая на экране его содержимое, будет выглядеть так:
int main(void)
{
Printer printer; //Конструктор инициализирует
//переменные объекта
printer.show();
return 0;
}
При выполнении этой программы на экран будет выведено сообщение:
Model: Canon_BJC250 year: 2000 status: 0
Нетрудно заметить, что используя этот конструктор для создания нескольких объектов, получаем объекты с одинаковыми значениями свойств.
Чтобы получать каждый раз объекты с новыми значениями свойств, используется конструктор с параметрами:
class Printer
{
…
public:
//Конструктор с параметрами
Printer(char* _model, int _year);
…
};
где _model – имя параметра, соответствующего значению модели, _year – имя параметра, соответствующего значению года.
Замечание. Имена параметрам могут быть даны любые, но удобно, когда имена параметров совпадают с названиями соответствующих свойств, отличаясь от них лишь первым символом _ (знак подчеркивания). Такой прием позволяет не запутаться при написании конструктора. Однако применять его можно лишь в том случае, если компилятор позволяет ставить знак _ в начале идентификатора.
Теперь конструктор будет выглядеть так:
Printer :: Printer(char* _model, int _year)
{
strcpy(model, _model);
year=_year;
status=0;
}
Воспользуемся конструктором с параметрами для создания в программе двух объектов с различными свойствами:
int main(void)
{
//Создание первого объекта
Printer printer1("HP5P",1999);
printer1.show();
//Создание второго объекта
Printer printer2("Canon_BJC250",2000);
printer2.show();
return 0;
}
При выполнении этой программы на экран будет выведено сообщение:
Model: HP5P year: 1999 status: 0
Model: Canon_BJC250 year: 2000 status: 0
В состав класса может быть включено несколько конструкторов, что обосновано таким свойством языка C++, как перегрузка функций. Конструкторы обязательно должны отличаться количеством или типами параметров, чтобы компилятор мог подобрать конструктор, соответствующий создаваемому объекту.
Класс может не содержать ни одного конструктора, в этом случае для создания объекта создается конструктор по умолчанию, который выделяет память под объект, но при этом не инициализирует переменные.
Для разрушения объекта используется метод, называемый деструктором. Для деструктора, также как и конструктора, не указывается тип возвращаемого значения, имя совпадает с именем класса, только перед именем помещается знак ~ (тильда).
Деструктор не имеет параметров и включается в раздел public:
class Printer
{
…
public:
Printer(char* _model, int _year); //Конструктор //с параметрами
~Printer(); //Деструктор
…
};
Деструктор может отсутствовать в составе класса, тогда для разрушения объекта создается деструктор по умолчанию. Деструктор обязательно должен быть включен в класс, если какие-либо свойства класса помещаются в динамической памяти.
Рассмотрим пример с классом Printer, где одно из свойств (название модели) помещается в динамической памяти:
class Printer
{
char* model; //указатель на строку, которая будет
//содержать название модели и разместится
//в динамической памяти
int year; //год выпуска
int status; //состояние принтера
public:
Printer(char* _model, int _year);
~Printer();
void set_print();
void stop_print();
void show();
};
Конструктор:
Printer :: Printer(char* _model, int _year)
{
int len=strlen(_model); //Определение длины
//строки
//Выделение памяти в динамической области
//для размещения строки и символа '\0'
model=new char[len+1];
strcpy(model, _model);
year=_year;
status=0;
}
Деструктор:
Printer :: ~Printer()
{
//Освобождение динамической памяти
delete[] model;
//Присваивание указателю значения пустого
//указателя, обязательно в Visual C++ 6.0
model = NULL;
}
Тогда программа, выполняющая все этапы работы с объектом, будет выглядеть так:
int main(void)
{
Printer printer("HP5P",1999); //Создание объекта
printer.show();
return 0;
}
Явный вызов деструктора не требуется, так как его вызов будет выполнен автоматически в точке программы, где объект должен быть разрушен в соответствии с его временем жизни.
Пример программы с комментарием
Передача параметра в конструктор
#include <conio.h>
#include <iostream.h>
class MyClass
{
int a; //В а будет передаваться значение из параметра
public:
MyClass(int); //Прототип конструктора с одним параметром int
void show_a(); //Прототип функции show_a();
}; //Закончили описание класса, обязательны точка с запятой
//Описываем методы класса MyClass вне класса
MyClass::MyClass(int N) //Конструктор принимает один параметр в N
{
a=N; //В a из MyClass присваивается значение равное N
}
void MyClass::show_a() //show_a() есть метод класса MyClass
{
cout<<a; //Выводим a на экран
return;
}
// Все нужные методы уже описали
MyClass obj(int);
//Обратите внимание, что строчкой выше, в объект obj1 передается параметр int, который мы собираемся передать в конструктор объекта obj1. Если надо передать в 2 объекта, то было бы MyClass obj1(int),obj2(int); и далее по аналогии. Количество параметров и Тип который передается в объект, взят из прототипа описанного в конструкторе. MyClass(int) -> obj(int)
void main()
{
int a; //Переменная а действует только внутри main()
clrscr(); //Очищаем экран от всего ненужного
cout<<"Wwedi a: ";
cin>>a; //Присваиваем в a значение введенное с клавиатуры
//Теперь это а нужно передать в конструктор класса MyClass(int) в качестве параметра int
MyClass obj1=MyClass(a); //а Передается в конструктор класса MyClass в качестве параметра
obj1.show_a(); //Открытый метод из класса MyClass отображает а из метода MyClass
getch();
return;
}
В этом примере а внутри main и a внутри класса совершенно разные переменные. При выполнении функции main сначала выполняется код из функции main(), который очищает экран, предлагает ввести a и присваивает значение в a функции main. После идет обращение к объекту obj1 - С помощью строчки MyClass obj1=MyClass(a) в конструктор объекта obj1 передается параметр a. В конструкторе это значение как эстафету принимает переменная N
MyClass::MyClass(int N) Внутри конструктора есть своя переменная a Это переменная из класса MyClass. (Переменная a Класса к переменной a из функции main совершенно никакого отношения не имеет. Это разные переменные, названные одним именем)
Когда срабатывает конструктор, в переменную а из класса MyClass присваивается значение из N. Таким образом N Передал полученную эстафетную палочку далее и по назначению вовнутрь класса