Изпълнението на C++ конструктори и деструктори за обекти от произволен клас

Задача на C++ за конструктори и деструктори от произволен клас

Да се дефинират класовете People, Student и PStudent, така че инициализиращите действия да се изпълняват от подходящи конструктори. Разрушителните действия да се извършват от деструктори (destructors).

#include
#include
// декларация на класа People
class People
{public:
People(char * = “”, char * = “”);
void PrintPeople() const;
~People();
private:
char * name;
char * egn;
};

// дефиниция на конструктора на People
People::People(char *str, char *num)
{name = new char[strlen(str)+1];
strcpy(name, str);
egn = new char[11];
strcpy(egn, num);
}
// дефиниция на метода PrintPeople
void People::PrintPeople() const
{cout << “Ime: ” << name << endl;
cout << “EGN: ” << egn << endl;
}
// дефиниция на деструктора на People
People::~People()
{cout << “~People(): ” << endl;
delete name;
delete egn;
}
// декларация на класа Student
class Student : People
{public:
Student(char * = “”, char * = “”, long = 0, double = 0);
void PrintStudent() const;
~Student()
{cout << “~Student(): ” << endl;
}
private:
long facnom;
double usp;
};
//дефиниция на конструктора на класа Student
Student::Student(char *str, char * num, long facn,
double u) : People(str, num)
{facnom = facn;
usp = u;
}
// дефиниция на метода PrintStudent
void Student::PrintStudent() const
{PrintPeople();
cout << “Fac. nomer: ” << facnom << endl;
cout << “Uspeh: ” << usp << endl;
}
// декларация на класа PStudent
class PStudent : public Student
{public:
PStudent(char * = “”, char * = “”, long = 0,
double = 0, double = 0);
~PStudent()
{cout << “~PStudent() \n”;
}
void PrintPStudent() const;
protected:
double tax;
};
// дефиниция на конструктора на класа PStudent
PStudent::PStudent(char *str, char *num, long facn,
double u, double t) : Student(str, num, facn, u)
{tax = t;
}
// дефиниция на метода PrintPStudent
void PStudent::PrintPStudent() const
{PrintStudent();
cout << “Tax: ” << tax << endl;
}
void main()
{People pe;
pe.PrintPeople();
PStudent PStud(“Ivan Ivanov”, “8206123422″, 42444, 6.0, 4567);
PStud.PrintPStudent();
}
Резултат:
Ime:
EGN:
Ime: Ivan Ivanov
EGN: 8206123422
Fac.nomer: 42444
Uspeh: 6
Tax: 4567
~PStudent()
~Student()
~People()
~People()

Тази програма на C++ илюстрира използването на конструктори и деструктори на производни класове. Методите ReadPeople, ReadStudent и ReadPStudent на класовете People, Student и PStudent са заменени с конструктори. Освен това е добавен деструктор на class People, който освобождава паметта на динамичните член-данни name и egn на People. Деструкторите на класовете Student и PStudent са напълно излишни, тъй като собствените им член-данни не са динамични. Дефинирани са с цел илюстрация на реда на изпълнението на деструкторите на класовете. При създаването на обекта PStud се извиква конструкторът на класа PStudent. Преди изпълнението на тялото му се прави обръщение към конструктора (constructor) Student(“Ivan Ivanov”, “8206123422″, 42444, 6.0), т.е. започва създаване на обект от класа Student. Преди изпълнението на тялото на този конструктор се изпълнява обръщението People(“Ivan Ivanov”, “8206123422″), което инициализира компонентите name и egn с “Ivan Ivanov” и “8206123422″ съответно. Процесът на оценяване продължава с изпълнение на тялото на конструктора (constructor) на класа (class) Student, в резултат на което компонентите facnom и usp се инициализират с 42444 и 6 съответно. Най-накрая се изпълнява тялото на конструктора на класа PStudent, при което компонентата tax на обекта PStud се инициализира с 4567. Обръщението Stud.PrintPStudent() извежда отначало наследените член-данни, а след това и собствените член-данни на класа PStudent. Накрая се разрушава обектът PStud като преди това се извикват деструкторите на PStudent, Student и People.
Ако заменим дефинирания в класа People конструктор с два подразбиращи се параметъра с конструкторите

People::People(char *str, char *num)
{name = new char[strlen(str)+1];
strcpy(name, str);
egn = new char[11];
strcpy(egn, num);
}
и
People::People()
{name = “”;
egn = “”;
}

дефиницията
People pe;
ще предизвика обръщение към конструктора People() и член-данните на pe ще се инициализират с празния низ. При завършване на блока, изпълнението на деструктора ~People() ще направи опит да разруши несъществуващи връзки на name и egn с динамичната памет. Това ще предизвика грешка по време на изпълнение.
Ще отбележим също, че в инициализиращия списък на производния клас участват обръщения само към неговите базови класове. Дефиниция от вида:

PStudent::PStudent(char *str, char *num, long facn,
double u, double t) : People(str, num)
{tax = t;
}

предизвиква синтактична грешка – People не е основен клас на класа PStudent.
Ще отбележим също още една често допускана грешка.
В основния клас динамична променлива е дефинирана като protected. По такъв начин тя е видима и може пряко да се използва от всички член-функции на производния клас. Тъй като тази динамична променлива е наследена член-данна на производния клас, често се прави опит заетата от тази променлива памет да се освободи два пъти – веднъж от деструктора на базовия и веднъж от деструктора на производния клас. Това предизвиква грешка по време на изпълнение.
Пример: Дефиницията на деструктора на класа Student:

class People
{public:
People(char * = “”, char * = “”);
void PrintPeople() const;
~People();
protected:
char * name;
char * egn;
};
People::People(char *str, char *num)

void People::PrintPeople() const

People::~People()
{cout << “~People(): ” << endl;
delete name;
delete egn;
}
class Student : People
{public:
Student(char * = “”, char * = “”, long = 0, double = 0);
void PrintStudent() const;
~Student();
private:
long facnom;
double usp;
};
Student::Student(char *str, char * num, long facn,
double u) : People(str, num)

Student::~Student()
{cout << “~Student(): ” << endl;
delete name;
delete egn;
}
void Student::PrintStudent() const

е неправилна заради двойното освобождаване на динамична памет. Някои дефиниции са пропуснати, тъй като са същите като в задача 160.

Сходни статии:

  1. Изпълнението на конструктори и деструктори за обекти от произволен клас Ако базовият клас в C++ е деклариран като protected в производния клас, private компонентите му се наследяват като private, а public и protected – като protected. Пример: Ако class base...
  2. Пример за обектно ориентирана реализация на свързан стек Ще се възползваме от тясната връзка между св. списъци и стекове чрез повторно използване на класа на списъците. Ще приложим 2 разновидности на повторното използване. Отначало ще реализираме класа на...
  3. Търсене на нов елемент по ключ и добавяне на нов елемент в свързан списък void search ( student *first, unsigned key, float value ) // студент с ф. № key и с value се задава новия му успех { student *ptr = first; while...
  4. Пример за обектно – ориентирана реализация на свързан списък В примера се използва шаблон на класа List за обработка на списък от данни от цял тип и списък от данни с плаваща точка. Програма driver дава възможност да се...
  5. Задача: автоматизиране на работата на диспечер I. Условие Задача 24: Да се автоматизира дейността на диспечер на градския транспорт в град София. II. Анализ Диспечерът в автотранспорта има широко поле за реализация и практически може да...

Студио за уеб дизайн услуги, изработка на сайтове, SEO оптимизация и Интернет реклама Seven Web Design представя своите професионални уеб дизайн умения на високо ниво. Seven Web Design е продукт на Уеб Дизайн България Груп ООД ®
Comments are closed.