c++ primer plus(17章- 输入、输出和文件17.8-6习题)(有一点多重继承时数据持久化存储的思路)

问题:考虑14章的编程练习5中的类定义。完成下面的任务。

编写一个程序,他使用标准C++ I/O 、文件I/O 以及14章的编程练习5中定义的employee、manager、fink和highfink类型的数据。

该程序应包含程序清单17.17中的代码行,即允许用户将新数据添加到文件中。改程序首次被运行时,将要求用户输入数据,然后显示所有的数据,并将这些信息保存到文件中。当改程序再次被运行时,将首先读取并显示文件中的数据,然后让用户添加数据,并显示所有的数据。

差别之一是,应通过一个指向employee类型的指针数组来处理数据。这样指针可以指向employee对象,也可以指向从employee 派生出来的其他三种对象中的任何一种。使数组较小有助于检查程序, 例如, 您可能将数组限定为最多包含10个元素:

const int MAX = 10;     //no more than 10 objects

……

employee* pc[MAX];

为通过键盘输入,程序应使用一个菜单,让用户选择要创建的对象类型。菜单项使用一个switch,以便使用new 来创建指定类型的对象, 并将它的地址赋给pc数组中的一个指针。然后改对象可以使用虚函数setall()来提示用户输入相应的数据:

pc[i]->setall();    //invokes function corresponding to type of object

为将数据保存到文件中,应设计一个虚函数writeall();

for(int i = 0; i< index; i++)

    pc[i]->wirteall(fout);    //fout ofsteam connected to output file

注意:对于这个联系,应使用文本I/O , 而不是二进制 I/O(遗憾的是,徐对象包含指向虚函数指针表的指针,而write()将把这种信息复制到文件中。使用read()读取文件额内容,以填充对象时,函数指针值将为乱码, 这将扰乱虚函数的行为)。可使用换行符将字段分隔开,这样在输入时将很容易识别各个字段。也可以使用二进制I/O , 但不能将对象作为一个整体写入, 而应该提供分别对每个类成员应用write() 和 read()的类方法。这样,程序将只把所需的数据保存到文件中。

 

比较难处理的部分是使用文件恢复数据,问题在于:程序如何才能知道接下来要恢复的项目是employee对象、manager对象、fink对象还是highfink对象?一种方法是,在对象的数据写入文件时,在数据前面加上一个指示对象类型的整数。这样,在文件输入时,程序便可以读取该整数,并使用switch语句创建一个适当的对象来接收数据:
 

enum classkind{Employee, Manager, Fink, HighFink};

...

int classtype;

while((fin>> classtype).get(ch))

{
    switch(classtye)
    {
        case Employee:
            pc[i] = new employee();
            break;
    }
}

然后便可以使用指针调用虚函数getall()来读取信息:

pc[i] -> getall();

 

---------------------------------------------------------------------------------------------------------------------

以下为简单的类实现, 并没有实现题目的所有要求。

 

abstr_emp.h

#ifndef ABSTR_EMP_H
#define ABSTR_EMP_H

#include <iostream>
#include <string>

enum classKind{ Abstr_emp, Employee, Manager, Fink, Highfink };

class abstr_emp
{
public:
    abstr_emp();
    abstr_emp(const std::string& fn, const std::string & ln, const std::string &j);
    virtual ~abstr_emp() = 0;

public:
    virtual void ShowAll() const;
    virtual void SetAll();
protected:
    int m_iClassType;
    virtual void Data() const;
    virtual std::ostream& writeData(std::ostream& os);
    virtual std::istream& readData(std::istream& os);

public:
    virtual std::ostream& writeALL(std::ostream& os);
    virtual std::istream& readALL(std::istream& os);

    friend std::ostream& operator<<(std::ostream& os, const abstr_emp& e)
    {
        os << e.strFirstName << " " << e.strLastName << std::endl;
        return os;
    }
private:
    std::string strFirstName;
    std::string strLastName;
    std::string strJob;
};

class employee : public abstr_emp
{
public:
    employee();
    employee(const std::string& fn, const std::string & ln, const std::string &j);
    ~employee();
    
public:
    virtual void ShowAll() const;
    virtual void SetAll();

protected:
    virtual void Data() const;
    virtual std::ostream& writeData(std::ostream& os);
    virtual std::istream& readData(std::istream& os);
public:
    virtual std::ostream& writeALL(std::ostream& os);
    virtual std::istream& readALL(std::istream& os);
};

class manager : virtual public abstr_emp
{
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);
    ~manager();

public:
    virtual void ShowAll() const;
    virtual void SetAll();
protected:
    virtual void Data() const;
    virtual std::ostream& writeData(std::ostream& os);
    virtual std::istream& readData(std::istream& os);

public:
    virtual std::ostream& writeALL(std::ostream& os);
    virtual std::istream& readALL(std::istream& os);

private:
    int inchargeof;
protected:
    int InChargeOf() const { return inchargeof; }
    int& InChargeOf() { return inchargeof; }
};

class  fink : virtual public abstr_emp
{
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);
    ~fink();

public:
    virtual void ShowAll() const;
    virtual void SetAll();
public:
    virtual std::ostream& writeALL(std::ostream& os);
    virtual std::istream& readALL(std::istream& os);

protected:
    virtual void Data() const;
    virtual std::ostream& writeData(std::ostream& os);
    virtual std::istream& readData(std::istream& os);
private:
    std::string strReportsto;
protected:
    const std::string ReportsTo() const { return strReportsto; }
    std::string & ReportsTo() { return strReportsto; }
};

class highfink : public manager, public 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);

    ~highfink();

public:
    virtual void ShowAll() const;
    virtual void SetAll();

public:
    virtual std::ostream& writeALL(std::ostream& os);
    virtual std::istream& readALL(std::istream& os);

protected:
    virtual void Data() const;
    virtual std::ostream& writeData(std::ostream& os);
    virtual std::istream& readData(std::istream& os);
};

#endif

abstr_emp.cpp

 

#include "stdafx.h"
#include "abstr_emp.h"

abstr_emp::abstr_emp()
{
    printf("abstr_emp create.\n");
}

abstr_emp::abstr_emp(const std::string& fn, const std::string & ln, const std::string &j)
:strFirstName(fn),
strLastName(ln),
strJob(j)
{
    printf("abstr_emp create, first name = %s, last name = %s, job = %s .\n",fn.c_str(), ln.c_str(), j.c_str());
}

abstr_emp::~abstr_emp()
{
    printf("abstr_emp destroy.\n");
}

void abstr_emp::ShowAll() const
{
    printf("abstr_emp ShowAll, call data() function.\n");
    Data();
}

void abstr_emp::SetAll()
{
    printf("abstr_emp SetAll.\n");
}

void abstr_emp::Data() const
{
    printf("abstr_emp Data, first name = %s, last name = %s, job = %s.\n", strFirstName.c_str(), strLastName.c_str(), strJob.c_str());
}

std::ostream& abstr_emp::writeData(std::ostream& os)
{
    os << Abstr_emp << std::endl;
    os << strFirstName << std::endl;
    os << strLastName << std::endl;
    os << strJob << std::endl;
    return os;
}

std::istream& abstr_emp::readData(std::istream& os)
{
    os >> m_iClassType;
    if (m_iClassType == Abstr_emp)
    {
        os >> strFirstName;
        os >> strLastName;
        os >> strJob;
        //std::getline(os, strFirstName);
        //std::getline(os, strLastName);
        //std::getline(os, strJob);
    }
    return os;
}

std::ostream& abstr_emp::writeALL(std::ostream& os)
{
    return writeData(os);
}

std::istream& abstr_emp::readALL(std::istream& os)
{
    return readData(os);;
}

employee::employee() :abstr_emp()
{
    printf("employee create.\n");
}

employee::employee(const std::string& fn, const std::string & ln, const std::string &j)
:abstr_emp( fn,  ln, j)
{
    printf("employee create, first name = %s, last name = %s, job = %s .\n", fn.c_str(), ln.c_str(), j.c_str());
}

employee::~employee()
{
    printf("employee destroy.\n");
}

void employee::ShowAll() const
{
    printf("employee ShowAll. \n");
    abstr_emp::Data();
    Data();
}

void employee::SetAll()
{
    printf("employee SetAll.\n");
    abstr_emp::SetAll();
}

void employee::Data() const
{
    printf("employee Data.\n");
}

std::ostream& employee::writeData(std::ostream& os)
{
    os << Employee << std::endl;
    return os;
}

std::istream& employee::readData(std::istream& os)
{
    os >> m_iClassType;
    return os;
}

std::ostream& employee::writeALL(std::ostream& os)
{    
    writeData(os);
    return abstr_emp::writeData(os);
}

std::istream& employee::readALL(std::istream& os)
{
    readData(os);
    if (m_iClassType == Employee)
    {
        abstr_emp::readData(os);
    }
    return os;
}

manager::manager() :abstr_emp()
{
    printf("manager create.\n");
}

manager::manager(const std::string& fn, const std::string& ln, const std::string & j, int ico /*= 0*/)
: abstr_emp(fn, ln, j),
inchargeof(ico)
{
    printf("manager create, first name = %s, last name = %s, job = %s , inchargeof = %d.\n", fn.c_str(), ln.c_str(), j.c_str(), ico);
}

manager::manager(const abstr_emp& e, int ico)
:abstr_emp(e),
inchargeof(ico)
{
    printf("manager create with const abstr_emp .\n");
}

manager::manager(const manager& m)
:abstr_emp(m)
{
    printf("manager const manager&.\n");
    if (this != &m)
    {
        inchargeof = m.inchargeof;
    }
}

manager::~manager()
{
    printf("manager destroy.\n");
}

void manager::ShowAll() const
{
    printf("manager ShowAll. inchargeof = %d\n", inchargeof);
    abstr_emp::Data();
    Data();
}

void manager::SetAll()
{
    printf("manager SetAll.\n");
    abstr_emp::SetAll();
}

void manager::Data() const
{
    printf("manager Data. inchargeof = %d\n", inchargeof);
}

std::ostream& manager::writeData(std::ostream& os)
{
    os << Manager << std::endl;
    os << inchargeof << std::endl;
    return os;
}

std::istream& manager::readData(std::istream& os)
{
    os >> m_iClassType;
    if (m_iClassType == Manager)
    {
        os >> inchargeof;
    }
    return os;
}

std::ostream& manager::writeALL(std::ostream& os)
{
    writeData(os);
    return abstr_emp::writeALL(os);
}

std::istream& manager::readALL(std::istream& os)
{
    readData(os);
    if (m_iClassType == Manager)
    {
        abstr_emp::readData(os);
    }
    return os;
}

fink::fink()
:abstr_emp()
{
    printf("fink create.\n");
}

fink::fink(const std::string& fn, const std::string& ln, const std::string &j, const std::string &rpo)
: abstr_emp(fn, ln, j),
strReportsto(rpo)
{
    printf("fink create, first name = %s, last name = %s, job = %s , rpo = %s.\n", fn.c_str(), ln.c_str(), j.c_str(), rpo.c_str());
}

fink::fink(const abstr_emp& e, const std::string & rpo)
:abstr_emp(e),
strReportsto(rpo)
{
    printf("fink create with abstr_emp.\n");
}

fink::fink(const fink& e)
:abstr_emp(e)
{
    printf("fink create with const fink.\n");
    if (this != &e)
    {
        strReportsto = e.strReportsto;
    }
}

fink::~fink()
{
    printf("fink destroy.\n");
}

void fink::ShowAll() const
{
    printf("fink ShowAll. reportsto %s\n", strReportsto.c_str());
    abstr_emp::Data();
    Data();
}

void fink::SetAll()
{
    printf("fink SetAll.\n");
    abstr_emp::SetAll();
}

void fink::Data() const
{
    printf("fink Data, reportsto = %s.\n", strReportsto.c_str());
}

std::ostream& fink::writeData(std::ostream& os)
{
    os << Fink << std::endl;
    os << strReportsto << std::endl;
    return os;
}

std::istream& fink::readData(std::istream& os)
{
    os >> m_iClassType;
    if (m_iClassType == Fink)
    {
        os >> strReportsto;
    }
    return os;
}

std::istream& fink::readALL(std::istream& os)
{
    readData(os);
    if (m_iClassType == Fink)
    {
        abstr_emp::readData(os);
    }
    return os;
}

std::ostream& fink::writeALL(std::ostream& os)
{
    writeData(os);
    abstr_emp::writeData(os);
    return os;
}

highfink::highfink()
:manager(),
fink()
{
    printf("highfink create with manager , fink.\n");
}

highfink::highfink(const std::string& fn, const std::string & ln, const std::string & j, const std::string& rpo, int ico)
:manager(fn, ln, j, ico),
fink(fn,ln,j, rpo)
{
    printf("highfink create, first name = %s, last name = %s, job = %s , rpo = %s, ico = %d.\n", fn.c_str(), ln.c_str(), j.c_str(), rpo.c_str(), ico);
}

highfink::highfink(const abstr_emp& e, const std::string & rpo, int ico)
:manager(e, ico),
fink(e,rpo)
{
    printf("highfink create with manager , fink. rpo=%s, ico = %d\n", rpo.c_str(), ico);
}

highfink::highfink(const highfink & h)
:manager(h),
fink(h)
{
    if (this != &h)
    {
        
    }
}

highfink::highfink(const manager& m, const std::string & rpo)
:abstr_emp(m),
manager(m),
fink(m, rpo)
{
    printf("highfink create with manager and rpo.\n");
}

highfink::~highfink()
{
    printf("highfink destroy.\n");
}

void highfink::ShowAll() const
{
    printf("highfink ShowAll.\n ");
    abstr_emp::Data();
    Data();
}

void highfink::SetAll()
{
    printf("highfink SetAll.\n ");
    manager::SetAll();
    fink::SetAll();
}

std::ostream& highfink::writeALL(std::ostream& os)
{
    writeData(os);
    manager::writeData(os);
    fink::writeData(os);
    abstr_emp::writeData(os);
    return os;
}

std::istream& highfink::readALL(std::istream& os)
{
    readData(os);
    if (m_iClassType == Highfink)
    {
        manager::readData(os);
        fink::readData(os);
        abstr_emp::readData(os);
    }
    return os;
}

void highfink::Data() const
{
    manager::Data();
    fink::Data();
}

std::ostream& highfink::writeData(std::ostream& os)
{
    os << Highfink << std::endl;
    return os;
}

std::istream& highfink::readData(std::istream& os)
{
    os >> m_iClassType;
    return os;
}

测试代码:

#include <iostream>
#include "abstr_emp.h"

#define  WRITE_DATA
int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;

    std::string strFileName("temp_highfink.txt");

#ifdef WRITE_DATA
    employee temp_employee("em_first", "em_last", "em_job");
    manager temp_manager("ma_firest", "ma_last", "ma_job", 5);
    fink temp_fink("fin_first", "fink_last", "fink_job", "fink_reporto");
    highfink temp_highfink(temp_manager, "highfink_reporto");

    abstr_emp* pTempObj = &temp_highfink;   

    ofstream ofS(strFileName.c_str(), ios_base::app);
    if (ofS.is_open())
    {
        pTempObj->writeALL(ofS);
        ofS.clear();
        ofS.close();
    }
    else
    {
        cout << "create file empLoyee.txt failed.\n";
    }

#else

    ifstream ifS;
    ifS.open(strFileName.c_str(), ios_base::in);
    if (ifS.is_open())
    {
        char chType;
        chType = ifS.peek();
        int iType = chType - 48;
        abstr_emp* pTempObj = NULL;
        //{ Abstr_emp, Employee, Manager, Fink, Highfink };
        switch (iType)
        {
        case Employee:
            pTempObj = new employee();
            break;
        case Manager:
            pTempObj = new manager();
            break;
        case Fink:
            pTempObj = new fink();
            break;
        case Highfink:
            pTempObj = new highfink();
            break;
        default:
            break;
        }
        if (pTempObj)
        {
            pTempObj->readALL(ifS);
            pTempObj->ShowAll();

            delete pTempObj;
            pTempObj = NULL;
        }
    }
#endif     

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值