Деструктор

 

В класс можно также объявить и другую специальную функцию-член, называемую деструктор (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. Введение в библиотеки классов