Деструктор
В класс можно также объявить и другую специальную функцию-член, называемую деструктор (destructor), которая автоматически вызывается в момент разрушения объекта, т.е. его уничтожения в памяти. Деструктор имеет такое же имя как и класс, но со значком ~ перед именем. Деструкторы не могут ни возвращать, ни принимать значений. Деструктор в классе может быть только один.
// Пример 6.3.1
// Конструкторы и деструктор
#include <iostream>
using namespace std;
//Объявление класса Cat
class Cat {
public:
// члены-данные
int itsAge;
// специальные методы
Cat(); //конструктор по умолчанию (default constructor)
~Cat(); //деструктор (destructor)
// методы для работы с объектом
void Meow();
};
// реализация функций класса Cat
//конструктор
Cat::Cat() {
itsAge=2;
cout << "Конструктор Cat по умолчанию (default)\n";
}
//деструктор
Cat::~Cat() {
cout << "Деструктор Cat\n";
}
// методы
void Cat::Meow() {
cout << "Мяу\a\a\a\n";
}
int main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
Cat Vaska; // конструктор по умолчанию
cout << "Возраст кота Vaska = " << Vaska.itsAge << "\n";
Vaska.itsAge=7;
cout << "Возраст кота Vaska = " << Vaska.itsAge << "\n";
cin.get();
Cat Murka; // конструктор по умолчанию
cout << "Возраст кота Murka = " << Murka.itsAge << "\n";
cin.get();
}
// Пример 6.3.2
// Конструкторы и деструктор
#include <iostream>
using namespace std;
typedef unsigned short int USHORT;
enum Color {Single, Red, Black, Green };
// Объявление класса (class definition)
class Pencil {
public:
// члены-данные, свойства, поля (data members, properties, fields)
USHORT itsLength;
USHORT itsRadius;
bool itsEraser;
Color itsColor;
double itsPrice;
// члены-функции, методы (memmber-functions, methods)
// конструкторы - constructors (выполняет инициализацию объекта, имеет имя
// класса, вызывается автоматически при создании объекта)
Pencil(); // default-constructor #1
Pencil(USHORT,USHORT,bool,Color,double); // constructor #2
Pencil(int); // constructor #3 (int - flag)
// деструктор - destructor (имеет имя ~класс вызывается автоматически,
// при уничтожении объекта)
~Pencil();
// члены-функции, методы для ввода-вывода
void DisplayAllToScreen();
void GetAllFromKeyBoard();
};
// Реализация класса (class realization)
Pencil::Pencil() {
cout << "Конструктор по умолчанию #1" << endl;
itsLength=100;
itsRadius=10;
itsEraser=false;
itsColor=Single;
itsPrice=0.80;
}
Pencil::Pencil(USHORT l, USHORT r, bool e, Color c, double p) {
cout << "Конструктор #2" << endl;
itsLength=l;
itsRadius=r;
itsEraser=e;
itsColor=c;
itsPrice=p;
}
Pencil::Pencil(int) {
cout << "Конструктор #3" << endl;
GetAllFromKeyBoard();
}
Pencil::~Pencil() {
cout << "Деструктор" << endl;
}
void Pencil::DisplayAllToScreen() {
cout << itsLength << '\t' << itsRadius << '\t' << itsEraser << '\t'
<< itsColor << '\t' << itsPrice << endl;
}
void Pencil::GetAllFromKeyBoard() {
int color;
cout << "Введите длину, радиус, наличие резинки(0,1), цвет(0-3), цену >";
cin >> itsLength >> itsRadius >> itsEraser >> color >> itsPrice;
itsColor=(Color)color;
}
int main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
//создание объектов типа Pencil
Pencil p1; // вызывается конструктор без параметров (default #1)
p1.DisplayAllToScreen();
p1.GetAllFromKeyBoard();
p1.DisplayAllToScreen();
Pencil p2(50,8,false,Black,0.55); // вызывается конструктор с параметрами #2
p2.DisplayAllToScreen();
Pencil p3(0); // вызывается конструктор c int параметром #3
p3.DisplayAllToScreen();
cin.get();
return 0;
}
4. Классы и компилятор
Если конструктор и деструктор в классе не объявлены, то компилятор включит в состав класса конструктор по умолчанию и деструктор. Компиляторный конструктор по умолчанию инициализации объекта не выполняет. Компилятор в классах поддерживает также конструктор копирования (copy constructor), который используется системой при создании копии объекта и оператор присваивания (=). Другие операторы С++, такие как +, -, *, %, ++, --, >, <, = =, !=, >>, << и т.д. первоначально в классах отсутствуют и их нельзя использовать при работе с объектами (их тоже можно реализовать!).
// Пример 6.3.3
// Конструкторы, деструктор, конструктор копии, оператор =
#include <iostream>
using namespace std;
// объявление простейшего класса для работника фирмы
// члены-данные открыты
class Worker {
// открытые члены-данные
public :
unsigned long itsID; // табельный номер
char itsSurname[21]; // фамилия
int itsAge; // возраст
int itsYears; // стаж работы
double itsSalary; // зарплата
// открытые методы
public :
// Конструкторы
Worker();
Worker(unsigned long, char [], int, int, double);
Worker(int);
// Деструктор
~Worker();
// Функции
void WorkerToScreen();
void WorkerFromKeyBoard();
};
// реализация класса
// конструктор без параметров, по умолчанию , default constructor
Worker::Worker() {
cout << "Конструктор #1 (по умолчанию)" << endl;
itsID=0; strcpy(itsSurname,""); itsAge=0; itsYears=0; itsSalary=0;
}
// конструктор c параметрами
Worker::Worker(unsigned long id, char name[], int age, int years, double salary) {
cout << "Конструктор #2 с параметрами" << endl;
itsID=id; strcpy(itsSurname,name); itsAge=age; itsYears=years; itsSalary=salary;
}
// конструктор клавиатурный
Worker::Worker(int) {
cout << " Конструктор #3 (клавиатурный)" << endl;
WorkerFromKeyBoard();
}
// Деструктор
Worker::~Worker() {
cout << "Деструктор " << endl;
}
// Вывод сведений на экран
void Worker::WorkerToScreen() {
cout << itsID << '\t';
cout << itsSurname << '\t';
cout << itsAge << '\t';
cout << itsYears << '\t';
cout << itsSalary << endl;
}
void Worker::WorkerFromKeyBoard() {
cout << "Номер : ";
cin >> itsID;
cout << "Фамилия : ";
cin >> itsSurname;
cout << "Введите через пробел возраст, стаж, зарплату : ";
cin >> itsAge >> itsYears >> itsSalary;
}
void main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
Worker w1; // конструктор по умолчанию
w1.WorkerToScreen();
cin.get();
w1.itsID=100;
strcpy(w1.itsSurname,"Ivanov");
w1.itsAge=25;
w1.itsYears=5;
w1.itsSalary=500.56;
w1.WorkerToScreen();
cin.get();
Worker w2(100,"Petrov",30,5,300.50); // конструктор с параметрами
w2.WorkerToScreen();
cin.get();
Worker w3(0); // клавиатурный конструктор
w3.WorkerToScreen();
cin.get();
Worker Vasia(w1); // конструктор копирования
Vasia.WorkerToScreen();
cin.get();
Vasia=w2; // оператор присваивания
Vasia.WorkerToScreen();
cin.get();
// Так писать нельзя - эти операторы в классе не реализованы
// Vasia++;
// cout << Vasia;
// Vasia=w1+w2;
cin.get();
}
5. Классы с закрытыми данными. Медоды доступа.
В промышленных разработках применяется еще более сложная структура класса: : данные-члены объявляют приватными и для доступа к ним создают открытые методы доступа. Для доступа к private (закрытым) членам-данным необходимо разрабатывать и использовать открытыеметоды доступа (public accessor methods). Выделяют два типа методов доступа :
· set – установка (определение) значений членов-данных;
· get – получение (чтение) значений членов данных.
Методы доступа типа get лучше объявлять как const. Функции типа set не могут быть объявлены как const.
// Пример 6.3.4
// Объявление и реализация класса с закрытыми данными
#include <iostream>
using namespace std;
//Объявление класса Cat
class Cat {
// закрытые члены-данные
private:
int itsAge;
// открытые методы
public:
// специальные методы
// методы доступа
int getAge() const {return itsAge;} //inline
void setAge(int age){itsAge=age;} //inline
// конструкторы и деструктор
Cat(); //конструктор по умолчанию (default)
~Cat(); //деструктор
// методы для работы с объектом
void Meow();
};
// реализация функций класса Cat
//конструкторы
Cat::Cat() {
itsAge=2;
cout << "Конструктор Cat по умолчанию (default)\n";
}
//деструктор
Cat::~Cat() {
cout << "Деструктор Cat\n";
}
// методы
void Cat::Meow(){
cout << "Мяу\a\a\a\n";
}
void main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
Cat Frisky;
// ошибка доступа к закрытым данным
//Frisky.itsAge=3;
//cout << "Frisky is a cat who is " << Frisky.itsAge << " years old.\n";
// используем открытые методы доступа - ошибки доступа нет
cout << "Frisky is a cat who is " << Frisky.getAge() << " years old.\n";
Frisky.setAge(3);
cout << "Frisky is a cat who is " << Frisky.getAge() << " years old.\n";
Frisky.Meow();
cin.get();
//Frisky.itsAge=7; // ошибка - not accessiable
// используем открытые методы
Frisky.setAge(7);
cout << "Now Frisky is " << Frisky.getAge() << " years old.\n";
cin.get();
}
// Пример 6.3.5
// Объявление и реализация класса карандаша с закрытыми данными
#include <iostream>
using namespace std;
typedef unsigned short int USHORT;
enum Color {Single, Red, Black, Green };
// Объявление класса (class definition)
class Pencil {
private:
// члены-данные, свойства, поля
USHORT itsLength;
USHORT itsRadius;
bool itsEraser;
Color itsColor;
double itsPrice;
public:
// конструкторы
Pencil(); // default-constructor #1
Pencil(USHORT,USHORT,bool,Color,double); // constructor #2
Pencil(int); // constructor #3 - клавиатурный
~Pencil(); // деструктор
// методы доступа
void setLength(USHORT len) {itsLength=len;}
USHORT getLength() const {return itsLength;}
void setRadius(USHORT rad) {itsRadius=rad;}
USHORT getRadius() const {return itsRadius;}
void setEraser(bool er) {itsEraser=er;}
bool getEraser() const {return itsEraser;}
void setColor(Color col) {itsColor=col;}
Color getColor() const {return itsColor;}
void setPrice(double pr) {itsPrice=pr;}
double getPrice() const {return itsPrice;}
// методы класса
void DisplayAllToScreen();
void GetAllFromKeyBoard();
};
// Реализация класса
// Конструкторы и деструктор
Pencil::Pencil() {
cout << "Конструктор по умолчанию #1" << endl;
itsLength=0;
itsRadius=0;
itsEraser=false;
itsColor=Single;
itsPrice=0;
}
Pencil::Pencil(USHORT l, USHORT r, bool e, Color c, double p) {
cout << " Конструктор #2" << endl;
itsLength=l;
itsRadius=r;
itsEraser=e;
itsColor=c;
itsPrice=p;
}
Pencil::Pencil(int) {
cout << " Конструктор #3" << endl;
GetAllFromKeyBoard();
}
Pencil::~Pencil() {
cout << "Деструктор" << endl;
}
// множество других методов класса
void Pencil::DisplayAllToScreen(){
cout << itsLength << '\t' << itsRadius << '\t' << itsEraser << '\t'
<< itsColor << '\t' << itsPrice << endl;
}
void Pencil::GetAllFromKeyBoard(){
int color;
cout << "Введите длину, радиус, наличие резинки(0,1), цвет(0-3), цену>";
cin >> itsLength >> itsRadius >> itsEraser >> color >> itsPrice;
itsColor=(Color)color;
}
int main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
//создание объектов типа Pencil
Pencil p1; // вызывается конструктор без параметров (default #1)
p1.DisplayAllToScreen();
//p1.GetAllFromKeyBoard();
//p1.DisplayAllToScreen();
Pencil p2(50,8,false,Black,0.55); // вызывается конструктор с параметрами #2
p2.DisplayAllToScreen();
Pencil p3(0); // вызывается конструктор c int параметром #3
p3.DisplayAllToScreen();
// используем методы доступа
p3.setColor(Red);
p3.DisplayAllToScreen();
//double sred=(p1.itsPrice + p2.itsPrice + p3.itsPrice)/3.; // access error
double sred=(p1.getPrice()+p2.getPrice()+p3.getPrice())/3.;
cout << sred << endl;
cin.get();
return 0;
}
// Пример 6.3.6
// Объявление и реализация класса для работника фирмы с закрытыми данными
#include <iostream>
using namespace std;
class Worker {
// закрытые члены-данные
private :
unsigned long itsID; // табельный номер
char itsSurname[20]; // фамилия
int itsAge; // возраст
int itsYears; // стаж работы
double itsSalary; // зарплата
// открытые методы
public :
// Конструкторы
Worker();
Worker(unsigned long, char[], int, int, double);
Worker(int);
// Деструктор
~Worker();
// Методы доступа
unsigned long getID() const {return itsID;}
void setID(unsigned long id) {itsID=id;}
const char * getSurname() const {return itsSurname;}
void setSurname(char name[]) {strcpy(itsSurname,name);}
int getAge() const {return itsAge;}
void setAge(int age) {itsAge=age;}
int getYears() const {return itsYears;}
void setYears(int years) {itsYears=years;}
double getSalary() const {return itsSalary;}
void setSalary(double salary) {itsSalary=salary;}
// Методы класса
void WorkerToScreen();
void WorkerFromKeyBoard();
};
// реализация класса
// конструктор без параметров, по умолчанию , default constructor
Worker::Worker() {
cout << "Конструктор #1 (по умолчанию)" << endl;
itsID=0; strcpy(itsSurname,""); itsAge=0; itsYears=0; itsSalary=0;
}
// конструктор c параметрами
Worker::Worker(unsigned long id, char name[], int age, int years, double salary) {
cout << "Конструктор #2 с параметрами" << endl;
itsID=id; strcpy(itsSurname,name); itsAge=age; itsYears=years; itsSalary=salary;
}
// конструктор клавиатурный
Worker::Worker(int){
cout << "Конструктор #3 (клавиатурный)" << endl;
WorkerFromKeyBoard();
}
// Деструктор
Worker::~Worker(){
cout << "Деструктор " << endl; cin.get();
}
// Вывод сведений на экран
void Worker::WorkerToScreen(){
cout << itsID << '\t';
cout << itsSurname << '\t';
cout << itsAge << '\t';
cout << itsYears << '\t';
cout << itsSalary << endl;
}
// Ввод сведений c клавиатуры
void Worker::WorkerFromKeyBoard() {
cout << "Номер : ";
cin >> itsID;
cout << "Фамилия : ";
cin >> itsSurname;
cout << "Введите через пробел возраст, стаж, зарплату : ";
cin >> itsAge >> itsYears >> itsSalary;
}
void main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
Worker w1; //создание объекта - конструктор по умолчанию
w1.setID(100);
w1.setSurname("Baranov");
w1.setAge(145);
w1.setYears(10);
w1.setSalary(600.78);
w1.WorkerToScreen();
cin.get();
Worker w2(100,"Kozlov",30,5,300.50); // конструктор с параметрами
w2.WorkerToScreen();
cin.get();
Worker w3(0); // клавиатурный конструктор
w3.WorkerToScreen();
cin.get();
Worker Vasia(w1); // конструктор копирования
Vasia.WorkerToScreen();
cin.get();
Vasia=w2; // оператор присваивания
Vasia.WorkerToScreen();
cin.get();
}
6. Структуры в С++
В языке С ближайшим родственником понятия класс является структура struct. В С++ структуры остались. По умолчанию в структурах уровень доступа открытый – public. Структуру можно объявить и использовать точно также как и класс, определив в ней нужные уровни доступа. Современная методика написания программ на С++ рекомендует отказаться от использования понятия структуры в программах.
// Пример 6.3.7
// Пример программы с struct C++
#include <iostream>
using namespace std;
// объявление структуры C++ - по умолчанию все открыто
struct Employee {
int Age;
int YearsOfService;
double Salary;
void SetEmp(int a,int y,double s);
void ViewEmp();
};
// реализация методов структуры C++
void Employee::SetEmp(int a,int y,double s){
Age=a; YearsOfService=y; Salary=s;
}
void Employee::ViewEmp(){
cout << Age << '\t' << YearsOfService << '\t' << Salary << endl;
}
// главная функция
void main() {
setlocale( LC_ALL, "Russian"); // для вывода на экран русского текста
Employee W1;
W1.Age=34; W1.YearsOfService=4; W1.Salary=987.65;
cout << W1.Age << '\t' << W1.YearsOfService << '\t' << W1.Salary << endl;
cin.get();
Employee W2;
W2.SetEmp(22,2,500);
W2.ViewEmp();
cin.get();
}
Лекция 6.4. Введение в библиотеки классов