C++ Premier Plus 6th edition - Programming excercise - Chapter17 - 6

未将对象作为整体写入和读出,此种方式待再写一版。
本次是将对象中的信息拆分写入文件,再以读取每个字符的方式读取出所有文件内容。
emp.h

#ifndef EMP_H_
#define EMP_H_

// emp.h -- header file for abstr_emp class and children
#include <iostream>
#include <string>

using std::fstream;
class abstr_emp
{
private:
    std::string fname; // abstr_emp's first name
    std::string lname; // abstr_emp's last name
    std::string job;
public:
    abstr_emp();
    abstr_emp(const std::string & fn, const std::string & ln,
              const std::string & j);
    virtual void ShowAll() const; // labels and shows all data
    virtual void SetAll(); // prompts user for values
    virtual void Writeall(fstream& finout);// newly added for 17-6
    friend std::ostream & operator<<(std::ostream & os, const abstr_emp & e);
    // just displays first and last name
    virtual ~abstr_emp() = 0; // virtual base class
};
class employee : public abstr_emp
{
public:
    employee();
    employee(const std::string & fn, const std::string & ln,
             const std::string & j);
    virtual void ShowAll() const;
    virtual void SetAll();
    virtual void Writeall(fstream& finout);// newly added for 17-6
};
class manager : virtual public abstr_emp
{
private:
    int inchargeof; // number of abstr_emps managed
protected:
    // create protected methods allowing derived highfink
    // visit its vitual base-classes' newly added member (comparing
    // with same ancestor abstr_emp
    // ******************************************//
    // return value use int, but not const int,because returns a copy
    // no need to concern alter original value
    int InChargeOf() const { return inchargeof; } // output
    int & InChargeOf() { return inchargeof; } // input
public:
    manager();
    manager(const std::string & fn, const std::string & ln,
            const std::string & j, int ico = 0);
    manager(const abstr_emp & e, int ico);
    manager(const manager & m);
    virtual void ShowAll() const;
    virtual void SetAll();
    virtual void Writeall(fstream& finout);// newly added for 17-6
};
class fink : virtual public abstr_emp
{
private:
    std::string reportsto; // to whom fink reports
protected:
    const std::string ReportsTo() const { return reportsto; }
    std::string & ReportsTo() { return reportsto; }
public:
    fink();
    fink(const std::string & fn, const std::string & ln,
         const std::string & j, const std::string & rpo);
    fink(const abstr_emp & e, const std::string & rpo);
    fink(const fink & e);
    virtual void ShowAll() const;
    virtual void SetAll();
    virtual void Writeall(fstream& finout);// newly added for 17-6
};
class highfink : public manager, public fink // management fink
{
public:
    highfink();
    highfink(const std::string & fn, const std::string & ln,
             const std::string & j, const std::string & rpo,
             int ico);
    highfink(const abstr_emp & e, const std::string & rpo, int ico);
    highfink(const fink & f, int ico);
    highfink(const manager & m, const std::string & rpo);
    highfink(const highfink & h);
    virtual void ShowAll() const;
    virtual void SetAll();
    virtual void Writeall(fstream& finout);// newly added for 17-6
};
#endif

emp.cpp

// implementations
#include<iostream>
#include"emp.h"
#include<fstream>

using std::cout;
using std::endl;
using std::cin;
// implementations for class abstr_emp
abstr_emp::abstr_emp()
{
    fname = "default_fname";
    lname = "default_lname";
    job = "default_job";
}

abstr_emp::abstr_emp(const std::string & fn,
                     const std::string & ln,
                     const std::string & j) :fname(fn), lname(ln),
    job(j) {}

void abstr_emp::ShowAll() const
{
    cout << "Name: " << fname << " " << lname << endl
         << "Job: " << job << endl;
}

void abstr_emp::SetAll()
{
    cout << "Enter first name: ";
    cin >> fname;
    cout << "Enter last name: ";
    cin >> lname;
    cout << "Enter job: ";
    cin >> job;
}

void abstr_emp:: Writeall(fstream& finout)
{
    finout << "Name: " << fname << " " << lname << endl
           << "Job: " << job << endl;
}

std::ostream& operator<<(std::ostream & os, const abstr_emp & e)
{
    os << e.fname << " " << e.lname << endl;
    return os;
}

abstr_emp::~abstr_emp() {}

// implementations for class employee
// no new class-member added,all use base-class methods
employee::employee() :abstr_emp() {}

employee::employee(const std::string & fn,
                   const std::string & ln,
                   const std::string & j) : abstr_emp(fn, ln, j) {}
void employee::ShowAll() const { abstr_emp::ShowAll(); }

void employee::SetAll() { abstr_emp::SetAll(); }

void employee::Writeall(fstream& finout)
{
    abstr_emp::Writeall(finout);
}

// implementations for class manager
manager::manager() :abstr_emp() { inchargeof = 0; }

manager::manager(const std::string & fn, const std::string & ln, const std::string & j,
                 int ico) : abstr_emp(fn, ln, j), inchargeof(ico) {}

manager::manager(const abstr_emp & e,
                 int ico) : abstr_emp(e), inchargeof(ico) {}

manager::manager(const manager & m) : abstr_emp(
        m), inchargeof(m.inchargeof) {}

void manager::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "Manages " << InChargeOf() <<
         " employees." << endl;
}

void manager::SetAll()
{
    abstr_emp::SetAll();
    cout << "Enter the numbers of employees manages: ";
    cin >> InChargeOf();// or cin >> inchargeof
    // protected members are set for derived class,available within derived class
    // but object of derived class can't involk
    // for this function,can use private member inchargeof directly. Both are okay
}

void manager::Writeall(fstream& finout)
{
    abstr_emp::Writeall(finout);
    finout<< "Manages " << InChargeOf() <<
          " employees." << endl;
}

// implementations for class fink
fink::fink() :abstr_emp() {}

fink::fink(const std::string & fn,
           const std::string & ln,
           const std::string & j,
           const std::string & rpo) : abstr_emp(fn, ln, j),
    reportsto(rpo) {}

fink::fink(const abstr_emp & e,
           const std::string & rpo) : abstr_emp(e),
    reportsto(rpo) {}

fink::fink(const fink & e) : abstr_emp(e),
    reportsto(e.reportsto) {}

void fink::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "Reports to: " << reportsto << endl;
}

void fink::SetAll()
{
    abstr_emp::SetAll();
    cout << "Enter manager's name reports to: ";
    cin >> reportsto;
}

void fink::Writeall(fstream& finout)
{
    abstr_emp::Writeall(finout);
    finout << "Reports to: " << reportsto << endl;
}

// implementations for class highfink
highfink::highfink() :abstr_emp(), manager(),
    fink() {}

// manager has a constructor,it is: manager(fn,ln,j,ico)
highfink::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::highfink(const abstr_emp & e,
                   const std::string & rpo, int ico) : abstr_emp(e),
    fink(e, rpo), manager(e, ico) {}

// first, have to know we have to create abstr_emp,manager,fink
// second, we can create manager using ancestor's part from fink
// there is a constructor manager(const abstr_emp&,int)
// here we up-casting fink objec f to obstr_emp's object
highfink::highfink(const fink & f,
                   int ico) :abstr_emp(f), manager(f, ico), fink(f) {}

highfink::highfink(const manager & m,
                   const std::string & rpo) : abstr_emp(m), manager(m), fink(m, rpo) {}

// pointer and reference of base-class can points to derived class's derived class
highfink::highfink(const highfink & h) : abstr_emp(h), manager(h), fink(h) {}

// inside highfink,its functions can use protected methods of
// base-class (manager and fink)
void highfink::ShowAll() const
{
    // part of same ancestor
    abstr_emp::ShowAll();
    // part of one of base-classes manager,with help of protected methods
    cout << "Numbers of staff managed: " << manager::InChargeOf() << endl;
    // part of one of base-classes fink,with help of protected methods
    cout << "Reports to: " << fink::ReportsTo() << endl;
}

void highfink::SetAll()
{
    // part of same ancestor
    abstr_emp::SetAll();
    // part of one of base-classes manager,with help of protected methods
    cout << "Enter the numbers of employees manages: ";
    cin >> InChargeOf();// or cin >> inchargeof
    // part of one of base-classes fink,with help of protected methods
    cout << "Enter manager's name reports to: ";
    cin >> ReportsTo();
}

void highfink::Writeall(fstream& finout)
{
    abstr_emp::Writeall(finout);
    finout << "Numbers of staff managed: " << manager::InChargeOf() << endl;
    finout << "Reports to: " << fink::ReportsTo() << endl;
}
*/

main.cpp

#include<iostream>
#include<fstream>
#include<iomanip>// left,setw()
#include"emp.h"

using namespace std;
const int SIZE = 10;
// prototypes
void caseBlockSol(abstr_emp*& pt, fstream& finout, int n);
void Solicit(abstr_emp* ps[], const int SIZE, fstream& finout);
void ReadFile(fstream& finout);

int main()
{
    // solicit data from user
    abstr_emp* pt[SIZE];// base class pointers
    fstream finout;
    // remove contents in file,avoid logs of previous-run left
    finout.open("result.txt", ios_base::in | ios_base::out | ios_base::trunc);
    if (!finout.is_open())
    {
        cerr << "Failed to open file: " << "result.txt, Bye!\n";
        cin.get();
        exit(EXIT_FAILURE);
    }
    finout.close();
    // PART1: write to file
    Solicit(pt, SIZE, finout);// open and close file inside the function
    // PART2: read from file, show logs
    cout << "\nNow we've opened file, logs in it shown as below:\n";
    ReadFile(finout);
    // PART3: add logs of file
    cout << "\nNow you can add new logs to file.\n";
    abstr_emp* Newpt[SIZE];// use a new array storing pointers of newly added data
    Solicit(Newpt, SIZE, finout);
    // PART4: again, read from file, show logs
    cout << "\nNow we've opened file, logs in it shown as below:\n";
    ReadFile(finout);

    cout << "Program works fine. Bye!";
    cin.get();
    cin.get();
    return 0;
}

// statements for switch of Solicit()
template<typename T>
void caseBlockSol(abstr_emp*& pt, fstream& finout, int n)
{
    pt = new T;
    pt->SetAll();// fill obj from user
    cout << "\nHere is the log you input:\n";
    pt->ShowAll();
    // write to file,include a classtype-num and log
    //int classtype = n;
    //finout << classtype;
    pt->Writeall(finout);
    cout << "(Added to file successfully)\n";
}
// solicit data from user
void Solicit(abstr_emp* ps[], const int SIZE, fstream& finout)// accept array of base class pointers, fstream&
{
    // open and check if open successfully
    finout.open("result.txt", ios_base::in | ios_base::out | ios_base::app);// append, avoid cover
    if (!finout.is_open())
    {
        cerr << "Failed to open file: " << "result.txt, Bye!\n";
        cin.get();
        exit(EXIT_FAILURE);
    }
    // menu
    cout << "Enter a num to choose an options: \n";
    cout << left;// format out stream
    cout << setw(20) << "1. Employee" << setw(20) << "2. Manager" << "\n"
         << setw(20) << "3. Fink" << setw(20) << "4. Highfink" << endl;
    int choice;
    cin >> choice;
    // exclude invalid value to choice
    while (choice<= 0 || choice> 4)
    {
        cout << "Invalid choice, please input again: \n";
        cin >> choice;
    }
    // allow input multi-times,can interupt anytime
    int i = 0;
    char ch = 'y';
    while (i < SIZE && tolower(ch) != 'q')// max SIZE inputs, allow user to interupt
    {
        // switch options
        switch (choice)
        {
        case 1:
            caseBlockSol<employee>(ps[i], finout, 1);
            break;
        case 2:
            caseBlockSol<manager>(ps[i], finout, 2);
            break;
        case 3:
            caseBlockSol<fink>(ps[i], finout, 3);
            break;
        case 4:
            caseBlockSol<highfink>(ps[i], finout, 4);
            break;
        default:
            break;
        }
        // prompt if want to stop inputting
        cout << "\n( Q/q to quit input, anyother key to continue): ";

        while (cin.get() != '\n')// get rid of rest of input line
            continue;
        cin.get(ch);
        if (ch != 'q'&&ch != 'Q')
        {
            ch = 'y';// exclude white space
            // menu
            cout << "\n\nEnter a num to choose an options: \n";
            cout << left;// format out stream
            cout << setw(20) << "1. Employee" << setw(20) << "2. Manager" << "\n"
                 << setw(20) << "3. Fink" << setw(20) << "4. Highfink" << endl;
            cin >> choice;
            // exclude invalid value to choice
            while (choice <= 0 || choice > 4)
            {
                cout << "\nInvalid choice, please input again: \n";
                cin >> choice;
            }
        }
        i++;
    }
    finout.close();
    cout << "\nAll of you input written to file successfully. Input completed.\n";
}
// read logs from file
void ReadFile(fstream& finout)
{
    // open and check if open successfully
    finout.open("result.txt", ios_base::in | ios_base::out | ios_base::app);// append, avoid cover
    if (!finout.is_open())
    {
        cerr << "Failed to open file: " << "result.txt, Bye!\n";
        cin.get();
        exit(EXIT_FAILURE);
    }
    // show current logs of file
    char ch;
    while (!finout.eof())
    {
        finout.get(ch);
        cout << ch;
    }
    finout.close();// because Solicit() will open and close file again
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值