Witam,
Zadanie polega na tym aby napisać program, w którym standardowe i plikowe operacje wejścia-wyjścia języka C++ używane są w połączeniu z typami employee, manager, fink oraz highfink. Klasy dziedziczą po wirtualnej klasie bazowej abstr_emp. O tyle z wczytaniem danych do pliku nie ma problemu, to z odczytaniem jest gorzej. Do klas dodałem kilka metod wirtualnych: writeall() oraz getall(), które mają na celu umożliwić komunikacje z plikiem. Utworzyłem też tablice wskaźników na typ abstr_emp, do którego mają być wczytywane dane. (w zadaniu jest napisane, że to ma być tablica wskaźników na typ employee, ale bardziej mi to pasuje na wirtualną klasę bazową). W zadaniu jest też napisane jak odczytywać dane z pliku, określając na początku danych wartość całkowitą określającą typ występującego po niej obiektu. Później podczas wprowadzania danych program odczyta taką wartość, a następnie korzystając z konstrukcji switch utworzy odpowiedni obiekt, który te dane otrzyma:
enum classkind {Employee, Manager, Fink, Highfink}; //w pliku nagłówkowym
...
int classtype;
while((fin >> classtype).get(ch)) { //znak nowego wiersza odziela wartość całkowitą od danych
switch(classtype) {
case Employee : pc[i] = new employee;
break;
Poniżej kod źródłowy, plik nagłówkowy i implementacja. Aha i program nie może używać operacji binarnych I/O.
#include "stdafx.h"
#include "emp02.h"
#include <iostream>
#include <fstream>
#include <iomanip>
int main()
{
using namespace std;
const char * filename = "employers.txt";
const int MAX = 10;
abstr_emp * pc[MAX];
ifstream fin;
fin.open(filename, ios_base::cur);
int i = 0;
if (fin.is_open())
{
//wskaźnik na początek
fin.seekg(0);
//aktulna zawartosc pliku
cout << "Oto aktualna zawartosc pliku \"" << filename << "\":\n";
int classtype;
char ch;
while ((fin >> classtype).get(ch) && i < MAX)
{
switch (classtype)
{
case Employee : pc[i] = new employee;
break;
case Manager: pc[i] = new manager;
break;
case Fink: pc[i] = new fink;
break;
case Highfink: pc[i] = new highfink;
break;
}
pc[i++]->getall(fin);
}
if (fin.eof())
fin.clear();
else
{
cerr << "Blad przy probie odczytu pliku \"" << filename << "\".\n";
exit(EXIT_FAILURE);
}
}
fin.close();
int all = i; //ilość wczytanych plików
int index;
cout << "Podaj ile nowych pracownikow chcesz wprowadzic: ";
cin >> index;
while((index + all) > MAX)
{
cin.clear();
cout << "Podaj mniejsza liczbe: ";
cin >> index;
}
cout << "Podaj jakich pracownikow chcesz wprowadzic:\n";
cout << setw(19) << "1. pracownik" << setw(20) << "2. manager" << endl;
cout << setw(20) << "3. donosiciel" << setw(27) << "4. glo. donosiciel" << endl;
char choice;
for (i = all; i < index + all; i++)
{
cout << "\nOsoba nr " << (i + 1) << ": ";
(cin >> choice).get();
switch (choice)
{
case '1':
pc[i] = new employee;
pc[i]->SetAll();
break;
case '2':
pc[i] = new manager;
pc[i]->SetAll();
break;
case '3':
pc[i] = new fink;
pc[i]->SetAll();
break;
case '4':
pc[i] = new highfink;
pc[i]->SetAll();
break;
}
}
ofstream fout;
fout.open(filename, ios_base::app);
cout << "Koniec wprowadzania. Nastapi teraz skopiowanie do pliku.\n\n";
for (int i = all; i < index + all; i++)
pc[i]->writeall(fout);
for (int i = 0; i < index + all; i++)
{
pc[i]->ShowAll();
cout << endl;
}
for (int i = 0; i < index + all; i++)
{
delete pc[i];
}
system("PAUSE");
return 0;
}
#ifndef EMP_H_
#define EMP_H_
#include <iostream>
#include <string>
#include <fstream>
enum classkind { Employee, Manager, Fink, Highfink };
class abstr_emp
{
private:
std::string fname; //imię obiektu abstr_emp
std::string lname; //nazwisko obiektu abstr_emp
std::string job; //zawód obiektu abstr_emp
public:
abstr_emp()
: fname("noname"), lname("nolastname"), job("brak") {}
abstr_emp(const std::string & fn, const std::string & ln, const std::string & j)
: fname(fn), lname(ln), job(j) {}
virtual void ShowAll() const; //opisuje i wyświetla wszystkie dane
virtual void SetAll(); //prosi użytkownika o podanie wartości
//r17
virtual void writeall(std::ofstream & file);
virtual void getall(std::ifstream & file);
//////
friend std::ostream & operator<<(std::ostream & os, const abstr_emp & e);
//tylko wyświetla imię i nazwisko
virtual ~abstr_emp() = 0; //wirtualna klasa bazowa, wirtualny destruktor
};
class employee : public abstr_emp
{
public:
employee()
: abstr_emp() {}
employee(const std::string & fn, const std::string & ln, const std::string & j)
: abstr_emp(fn, ln, j) {}
virtual void ShowAll() const;
virtual void SetAll();
//r17
virtual void writeall(std::ofstream & file);
virtual void getall(std::ifstream & file);
~employee() {}
};
class manager : virtual public abstr_emp
{
private:
int inchargeof; //liczba obiektów abstr_emps, którymi zarządza
protected:
int InChargeOf() const { return inchargeof; } //wyjście
int & InChargeOf() { return inchargeof; } //wejście
public:
manager()
: abstr_emp(), inchargeof(0) {}
manager(const std::string & fn, const std::string & ln, const std::string & j, int ico = 0)
: abstr_emp(fn, ln, j), inchargeof(ico) {}
manager(const abstr_emp & e, int ico)
: abstr_emp(e), inchargeof(ico) {}
manager(const manager & m)
: abstr_emp(m), inchargeof(m.inchargeof) {} //nie wiem czemu tak trzeba ale teraz chodzi dobrze
virtual void ShowAll() const;
virtual void SetAll();
//r17
virtual void writeall(std::ofstream & file);
virtual void getall(std::ifstream & file);
~manager() {}
};
class fink : virtual public abstr_emp
{
private:
std::string reportso; //do kogo fink (donosiciel ) przesyła raport
protected:
const std::string ReportsTo() const { return reportso; }
std::string & ReportsTo() { return reportso; }
public:
fink()
: abstr_emp(), reportso("brak") {}
fink(const std::string & fn, const std::string & ln, const std::string & j, const std::string & rpo)
: abstr_emp(fn, ln, j), reportso(rpo) {}
fink(const abstr_emp & e, const std::string & rpo)
: abstr_emp(e), reportso(rpo) {}
fink(const fink & e)
: abstr_emp(e), reportso(e.reportso) {} //nie wiem czemu tak trzeba ale teraz chodzi dobrze
virtual void ShowAll() const;
virtual void SetAll();
//r17
virtual void writeall(std::ofstream & file);
virtual void getall(std::ifstream & file);
~fink() {}
};
class highfink : public manager, public fink //główny donosiciel
{
public:
highfink()
: abstr_emp(), manager(), fink() {}
highfink(const std::string & fn, const std::string & ln, const std::string & j, const std::string & rpo, int ico)
: abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rpo) {}
highfink(const abstr_emp & e, const std::string & rpo, int ico)
: abstr_emp(e), manager(e, ico), fink(e, rpo) {}
highfink(const fink & f, int ico)
: abstr_emp(f), manager(f, ico), fink(f) {}
highfink(const manager & m, const std::string & rpo)
: abstr_emp(m), fink(m, rpo), manager(m) {}
highfink(const highfink & h)
: abstr_emp(h), manager(h), fink(h) {}
virtual void ShowAll() const;
virtual void SetAll();
//r17
virtual void writeall(std::ofstream & file);
virtual void getall(std::ifstream & file);
~highfink() {}
};
#endif
#include "stdafx.h"
#include "emp02.h"
//metody klasy abstr_emp
void abstr_emp::ShowAll() const
{
using std::cout;
cout << "Imie: " << fname << "\n";
cout << "Nazwisko: " << lname << "\n";
cout << "Praca: " << job << "\n";
}
void abstr_emp::SetAll()
{
using std::cout;
cout << "Podaj imie: ";
getline(std::cin, fname);
cout << "Podaj nazwisko: ";
getline(std::cin, lname);
cout << "Podaj prace: ";
getline(std::cin, job);
}
//funkcja zaprzyjazniona
std::ostream & operator<<(std::ostream & os, const abstr_emp & e)
{
os << e.fname << " " << e.lname;
return os;
}
abstr_emp::~abstr_emp() {}
//metody klasy employee
void employee::ShowAll() const
{
std::cout << "Pracownik\n";
abstr_emp::ShowAll();
}
void employee::SetAll()
{
std::cout << "Pracownik\n";
abstr_emp::SetAll();
}
//metody klasy manager
void manager::ShowAll() const
{
std::cout << "Manager\n";
abstr_emp::ShowAll();
std::cout << "Liczba pracownikow, ktorymi zarzadza: " << InChargeOf() << "\n";
}
void manager::SetAll()
{
std::cout << "Manager\n";
abstr_emp::SetAll();
std::cout << "Podaj ilosc pracownikow, ktorymi zarzadza: ";
(std::cin >> InChargeOf()).get();
}
//metody klasy fink
void fink::ShowAll() const
{
std::cout << "Donosiciel\n";
abstr_emp::ShowAll();
std::cout << "Przesyla raport do: " << ReportsTo() << "\n";
}
void fink::SetAll()
{
std::cout << "Donosiciel\n";
abstr_emp::SetAll();
std::cout << "Do kogo przesyla raport: ";
getline(std::cin, ReportsTo());
}
//metody klasy highfink
void highfink::ShowAll() const
{
std::cout << "Glowny donosiciel\n";
abstr_emp::ShowAll();
std::cout << "Liczba pracownikow, ktorymi zarzadza: " << InChargeOf() << "\n";
std::cout << "Przesyla raport do: " << ReportsTo() << "\n";
}
void highfink::SetAll()
{
std::cout << "Glowny donosiciel\n";
abstr_emp::SetAll();
std::cout << "Podaj ilosc pracownikow, ktorymi zarzadza: ";
(std::cin >> InChargeOf()).get();
std::cout << "Do kogo przesyla raport: ";
getline(std::cin, ReportsTo());
}
//nowe funkcje z rozdz 17
void abstr_emp::writeall(std::ofstream & file)
{
file << fname << std::endl;
file << lname << std::endl;
file << job << std::endl;
}
void employee::writeall(std::ofstream & file)
{
file << Employee << std::endl;
abstr_emp::writeall(file);
}
void manager::writeall(std::ofstream & file)
{
file << Manager << std::endl;
abstr_emp::writeall(file);
file << InChargeOf() << std::endl;
}
void fink::writeall(std::ofstream & file)
{
file << Fink << std::endl;
abstr_emp::writeall(file);
file << ReportsTo() << std::endl;
}
void highfink::writeall(std::ofstream & file)
{
file << Highfink << std::endl;
abstr_emp::writeall(file);
file << ReportsTo() << std::endl;
file << InChargeOf() << std::endl;
}
//inne funkcje
void abstr_emp::getall(std::ifstream & file)
{
file >> fname;
file >> lname;
std::getline(file, job);
}
void employee::getall(std::ifstream & file)
{
abstr_emp::getall(file);
}
void manager::getall(std::ifstream & file)
{
abstr_emp::getall(file);
file >> inchargeof;
}
void fink::getall(std::ifstream & file)
{
abstr_emp::getall(file);
getline(file, ReportsTo());
}
void highfink::getall(std::ifstream & file)
{
abstr_emp::getall(file);
file >> InChargeOf();
getline(file, ReportsTo());
}