Задача 15

Задача 15:

  1. Создать иерархию состоящую из представленных классов.
  2. Реализовать в наследнике вызов конструктора родителя с использованием инициализаторов
  3. реализовать все необходимые конструкторы в родителе и наследнике.
  4. реализовать следующие операторы
    	- =
    	- ==(!=)
    	- <<
    	- >>
  5. реализовать запись/чтение с использованием потоков.
  6. реализовать обработку исключительных ситуаций при отсутствии файла для чтения экземпляров.
  7. Экземпляры класса необходимо поместить в контейнер STL. Выбор контейнера – обосновать.
  8. В программе использовать преобразования только в стиле C++.
  9. Реализовать распечатку всех экземпляров при помощи ostream_iterator.

Вариант 4: Школьник, студент, аспирант.

Code

#include <iostream>
#include <cstring>
#include <vector>
#include <iterator>
#include <algorithm>
#include <fstream>

/*Вариант 4
Школьник(schoolboy), студент(student), аспирант(postgraduate).
*/

using namespace std;
#pragma warning(disable :  4996 )

class schoolboy{//base class
	char *fio;
	int age;
	char *school;
public:
	schoolboy(){//конструктор по умолчанию
		fio = NULL;	age = 0; school = NULL;	};
	schoolboy(char *fio1, int age1, char *school1);//конструктор c инициализаторами
	schoolboy(const schoolboy &sch); //конструктор копирования
	~schoolboy(){
		delete [] fio;
		delete [] school;
	};
	virtual int get_age() { return age; };
	void set_age(int age) { this->age=age; };
	virtual char *get_fio(){ return fio; };
	virtual void set_fio(char *n){ fio = new char[strlen(n)+1]; strcpy(fio, n); };
	virtual char *get_school(){return school; };
	void set_school(char *s){ school = new char[strlen(s)+1]; strcpy(school, s); };
};
schoolboy::schoolboy(char *fio1, int age1, char *school1){//конструктор c инициализаторами
		age = age1;
		fio = new char[strlen(fio1)+1];
		strcpy(fio, fio1);
		school = new char[strlen(school1)+1];
		strcpy(school, school1);
};
schoolboy::schoolboy(const schoolboy &sch){ //конструктор копирования
		age = sch.age;
		fio = new char[strlen(sch.fio)+1];
		strcpy(fio, sch.fio);
	    school = new char[strlen(sch.school)+1];
            strcpy(school, sch.school);
};
class student: public schoolboy{//derived class
    char *university;
public:
	student(){university = NULL; };
    student(const student &st); //конструктор копирования
    student(char *university1, char *fio1, int age1, char *school1): schoolboy(fio1, age1, school1){
        //конструктор c инициализаторами и вызовом конструктора предка
    		university = new char[strlen(university1)+1];
		strcpy(university, university1);    
    };
    ~student(){	delete [] university;};
    virtual char *get_university(){ return university; };
    void set_university(char *u){ university = new char[strlen(u)+1]; strcpy(university, u); };
};

student::student(const student &st){
		university = new char[strlen(st.university)+1];
		strcpy(university, st.university);
};

class postgraduate: public student{
    char *postgr;
public:
    postgraduate(){postgr = NULL; };
    postgraduate(char *postgr1, char *university1, char *fio1, int age1, char *school1):
    student(university1, fio1, age1, school1){
        //конструктор c инициализаторами и вызовом конструктора предка
    		postgr = new char[strlen(postgr1)+1];
		strcpy(postgr, postgr1);    
    };
    postgraduate(const postgraduate &pg);// конструктор копирования
    ~postgraduate(){delete [] postgr;};
    char *get_postgr(){ return postgr; };
    void set_postgr(char *p){ postgr = new char[strlen(p)+1]; strcpy(postgr, p); };
    postgraduate operator=(postgraduate & );// перегрузка =
	friend bool operator==(postgraduate &op1, postgraduate &op2); //Перегрузка оператора "равно" через дружесивенную функцию
	friend bool operator!=(postgraduate &op1, postgraduate &op2);
	friend istream& operator>>(istream &is, postgraduate &P); //Перегрузка ввода данных через поток
	friend ostream& operator<<(ostream &os, postgraduate &P); //Перегрузка вывода данных через поток
	void save_to_file(ofstream &outF);
	void read_from_file(char *FileName);
	void print();
};
postgraduate::postgraduate(const postgraduate &pg){// конструктор копирования
		postgr = new char[strlen(pg.postgr)+1];
                strcpy(postgr, pg.postgr);
};

postgraduate postgraduate::operator=(postgraduate &pgtmp){
	set_fio( pgtmp.get_fio() );
	set_age( pgtmp.get_age() );
	set_school( pgtmp.get_school() );
	set_university( pgtmp.get_university() );
	strcpy( postgr, pgtmp.get_postgr() );

    return *this;
};

bool operator==(postgraduate &op1, postgraduate &op2){
	return op1.get_age()==op2.get_age();
};
bool operator!=(postgraduate &op1, postgraduate &op2){
	return op1.get_age()!=op2.get_age();
};

istream& operator>>(istream &is, postgraduate &P){
	int i;
	is >> i;
	P.set_age(i);
	return is;
};

ostream& operator<<(ostream &os, postgraduate &P){
	 os<<P.get_fio()<<"\t";
	 os<<P.get_age()<<"\t";
	 os<<P.get_school()<<"\t";
	 os<<P.get_university()<<"\t";
	 os<<P.get_postgr()<<"\t";
	 return os;
};

void postgraduate::save_to_file(ofstream &outF){
	outF<<get_fio()<<" "<<get_age()<<" "<<get_school()<<" "<<get_university()<<" "<<get_postgr()<<endl;
};

void postgraduate::read_from_file(char *FileName){
      ifstream inF;
	  inF.open(FileName, ios::in); 
      if (!inF)
      {
         cerr << endl << "Not open file: "<<endl;
         exit(1);
      }
	  cout<<"\n\n";
	char fio[20], fiolast[20], school[100], univer[100], postgr[100];
	int i;
	inF>>fio; cout<<fio; cout<<"\t";
	inF>>fiolast; cout<<fiolast; cout<<"\t";
	//set_name(fio);
	inF>>i; cout<<i; cout<<"\t";
	//set_age(i);
	inF>>school; cout<<school; cout<<"\t";
	inF>>univer; cout<<univer; cout<<"\t";
	inF>>postgr; cout<<postgr; cout<<"\t";
	
	 inF.close();
};
void postgraduate::print(){
	//cout <<"FIO:"<<get_fio()<< endl;
	cout <<"Age:"<<get_age()<< endl;
	cout <<"postgr:"<<postgr<< endl;
};

/* Чтобы достучаться до методов родителя нужно функции сделать виртуальными.
 * Или указатель преобразовать в указатель на предка.
*/
int main(){
	// STL
 /* Обоснование выбора контейнера STL: искать в контейнере мы ничего
 * не собираемся значит можно использовать класс vector
 */	
	vector <postgraduate *> ptr_vp; // вектор хранит указатели
	vector <postgraduate *>::iterator ptr_vp_iter;
	cout<<"\n"<<"size ptr_vp: "<<ptr_vp.size();
	postgraduate *p0 = new postgraduate("Aspirant0", "Univet #0", "Ira Akimenko", 32, "school #0");
	ptr_vp.push_back(p0); // поместить указатель в первый элемент массива
	ptr_vp.push_back(new postgraduate("Aspirant1", "Univet #1", "Dima", 34, "school #1"));
	ptr_vp.push_back(new postgraduate("Aspirant2", "Univet #2", "Puplik", 50, "school #2"));
	ptr_vp.push_back(new postgraduate("Aspirant3", "Univet #3", "pg101", 1319, "1"));
	ptr_vp.push_back(new postgraduate("Aspirant4", "Univet #4", "Pupkin", 50, "school #4"));
	

	cout<<"\n"<<"size ptr_vp: "<<ptr_vp.size();
	cout<<"\n";
	ofstream outF("class_to_file.txt", ios::app);
	int k=ptr_vp.size();
	for(int i=0; i<k; i++){
		cout<<ptr_vp[i]->get_fio()<<"\n";
		cout<<ptr_vp[i]->get_age()<<"\n";
		cout<<ptr_vp[i]->get_school()<<"\n";
		cout<<ptr_vp[i]->get_university()<<"\n";
		cout<<ptr_vp[i]->get_postgr()<<"\n";
		ptr_vp[i]->save_to_file(outF);
	}
	/* Освобождаем память выделенную NEW. То есть удаляем классы, на которые
        указывают указатели хранимые в векторе*/
	for (ptr_vp_iter=ptr_vp.begin();ptr_vp_iter!=ptr_vp.end();ptr_vp_iter++){
		delete *ptr_vp_iter;
	}

	cout<<"\n\n";
	//печатает содержимое вектора
	copy(ptr_vp.begin(), ptr_vp.end(), ostream_iterator<postgraduate *>(cout,"\t"));

	cout<<"\n";
	return 0;
}
PQ VPS сервера в 28+ странах.