C++ Primer Plus 第六版第十四章编程练习答案

本文探讨了C++中模板类的应用及多重继承的实现方式。通过具体案例,展示了模板类的定义与使用,以及如何在多重继承场景下解决二义性问题。文章还涉及了虚基类的概念,并给出了实例说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//question 1

//wine.h 
#ifndef WINE_H
#define WINE_H
#include <string>
#include <valarray>
template <class T1, class T2>
class Pair
{
    private:
        T1 a;
        T2 b;
    public:
        T1 & first();
        T2 & second();
        T1 first() const {return a;}
        T2 second() const {return b;}
        Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
        Pair() { }
};

template <class T1, class T2>
T1 & Pair<T1, T2>::first()
{
    return a;
}

template <class T1, class T2>
T2 & Pair<T1, T2>::second()
{
    return b;
}

typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;

class Wine
{
    private:
        std::string label;
        PairArray pr;
        int years;
    public:
        Wine();
        Wine(const char * l, int y, const int yr[], const int bot[]);
        Wine(const char * l, int y);
        void GetBottles();
        void Show() const;
        const std::string & Label() const {return label;}
        int sum() const;
};
#endif

 

//wine.cpp
#include "wine.h"
#include <iostream>
#include <valarray>

Wine::Wine() : label("none") , pr(), years(0)
{
}

Wine::Wine(const char * l, int y, const int yr[], const int bot[])
{
    label = l;
    years = y;
    ArrayInt a(yr, y);
    ArrayInt b(bot, y);
    pr = PairArray(a, b);
}

Wine::Wine(const char * l, int y)
{
    label = l;
    years = y;
    pr = PairArray();
}

void Wine::GetBottles()
{
    ArrayInt yr(years);
    ArrayInt bot(years);
    std::cout << "Enter " << label << " data for " << years << "year(s):\n";
    for (int i = 0; i < years; i++)
    {
        std::cout << "Enter year: ";
        std::cin >> yr[i];
        std::cout << "Enter bottles for that year: ";
        std::cin >> bot[i];
    }
    pr = PairArray(yr, bot);
}

void Wine::Show() const
{
    std::cout << "Wine: " << label << std::endl;
    std::cout << "\tYear" << "\t" << "Bottles" << std::endl;
    for(int i = 0; i < years; i++) std::cout << "\t" << (pr.first())[i] << "\t" << (pr.second())[i] << std::endl;
}

int Wine::sum() const
{
    int s = 0;
    for(int i = 0; i < years; i++)
    {
        s += (pr.second())[i];
    }
    return s;
}

//14_1.cpp
#include <iostream>
#include "wine.h"

int main(void)
{
    using std::cin;
    using std::cout;
    using std::endl;
    
    cout << "Enter name of wine: ";
    char lab[50];
    cin.getline(lab, 50);
    cout << "Enter number of years: ";
    int yrs;
    cin >> yrs;
    
    Wine holding(lab, yrs);
    holding.GetBottles();
    holding.Show();
    
    const int YRS = 3;
    int y[YRS] = {1993, 1995, 1998};
    int b[YRS] = {48, 60, 72};
    Wine more("Gushing Grape Red", YRS, y, b);
    more.Show();
    cout << "Total bottles for " << more.Label()
         << ": " << more.sum() << endl;
    cout << "Bye\n";
    return 0;
}

 

//question2

//wine2.h 
#ifndef WINE2_H
#define WINE2_H
#include <string>
#include <valarray>
template <class T1, class T2>
class Pair
{
    private:
        T1 a;
        T2 b;
    public:
        T1 & first();
        T2 & second();
        T1 first() const {return a;}
        T2 second() const {return b;}
        Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
        Pair() { }
        Pair & operator=(const Pair & p);
};

template <class T1, class T2>
T1 & Pair<T1, T2>::first()
{
    return a;
}

template <class T1, class T2>
T2 & Pair<T1, T2>::second()
{
    return b;
}

template <class T1, class T2>
Pair<T1, T2> & Pair<T1, T2>::operator=(const Pair<T1, T2> & p)
{
    a = p.a;
    b = p.b;
    return *this;
}

typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine : private PairArray, private std::string
{
    private:
        int years;
    public:
        Wine();
        Wine(const char * l, int y, const int yr[], const int bot[]);
        Wine(const char * l, int y);
        void GetBottles();
        void Show() const;
        const std::string & Label() const {return (const std::string &)(*this);}
        int sum() const;
};
#endif

//wine2.cpp
#include "wine2.h"
#include <iostream>
#include <valarray>

Wine::Wine() : std::string("none") , PairArray(), years(0)
{
}

Wine::Wine(const char * l, int y, const int yr[], const int bot[]) : std::string(l), years(y), PairArray(ArrayInt(yr, y), ArrayInt(bot, y))
{
}

Wine::Wine(const char * l, int y) : std::string(l), PairArray()
{
    years = y;
}

void Wine::GetBottles()
{
    ArrayInt yr(years);
    ArrayInt bot(years);
    std::cout << "Enter " << (const std::string &) (*this) << " data for " << years << "year(s):\n";
    for (int i = 0; i < years; i++)
    {
        std::cout << "Enter year: ";
        std::cin >> yr[i];
        std::cout << "Enter bottles for that year: ";
        std::cin >> bot[i];
    }
    PairArray::operator=(PairArray(yr, bot));
}

void Wine::Show() const
{
    std::cout << "Wine: " << (const std::string &) (*this) << std::endl;
    std::cout << "\tYear" << "\t" << "Bottles" << std::endl;
    for(int i = 0; i < years; i++) std::cout << "\t" << (PairArray::first())[i] << "\t" << (PairArray::second())[i] << std::endl;
}

int Wine::sum() const
{
    int s = 0;
    for(int i = 0; i < years; i++)
    {
        s += (PairArray::second())[i];
    }
    return s;
}

//14_2.cpp
#include <iostream>
#include "wine2.h"

int main(void)
{
    using std::cin;
    using std::cout;
    using std::endl;
    
    cout << "Enter name of wine: ";
    char lab[50];
    cin.getline(lab, 50);
    cout << "Enter number of years: ";
    int yrs;
    cin >> yrs;
    
    Wine holding(lab, yrs);
    holding.GetBottles();
    holding.Show();
    
    const int YRS = 3;
    int y[YRS] = {1993, 1995, 1998};
    int b[YRS] = {48, 60, 72};
    Wine more("Gushing Grape Red", YRS, y, b);
    more.Show();
    cout << "Total bottles for " << more.Label()
         << ": " << more.sum() << endl;
    cout << "Bye\n";
    return 0;
}

 

//question3

啊啊啊 这个题快把我折磨疯了 天天加班好困啊。。

//WORKER_H
#ifndef WORKER_H
#define WORKER_H
#include <string>
#include <iostream>

template <class T>
class QueueTp
{
    
    private:
        enum {Q_SIZE = 10};
        T * item;
        int top;
    public:
        explicit QueueTp(int qs = Q_SIZE);
        ~QueueTp() {delete [] item;}
        bool isempty() const;
        bool isfull() const;
        bool Push(const T & it);
        bool Pop();
        T & front() const; 
        T & rear() const;
};

template <class T>
T & QueueTp<T>::front() const
{
    return item[top-1];
}

template <class T>
T & QueueTp<T>::rear() const
{
    return item[0];

template <class T>
QueueTp<T>::QueueTp(int qs)
{
    item = new T[qs];
    top = 0;
}

template <class T>
bool QueueTp<T>::isempty() const
{
    return top == 0;
}

template <class T>
bool QueueTp<T>::isfull() const
{
    return top == Q_SIZE;
}

template <class T>
bool QueueTp<T>::Push(const T & it)
{
    if (isfull())
        return false;
    for (int i = top; i > 0; i--)
        item[i] = item[i-1];
    item[0] = it;
    top++;
    return true;
}

template <class T>
bool QueueTp<T>::Pop()
{
    if (isempty())
        return false;
    //delete item[top-1];
    top--;
    return true;
}

class Worker
{
    private:
        std::string fullname;
        long id;
    public:
        Worker() : fullname("no one"), id(0l) {   } 
        Worker(const std::string & s, long n) : fullname(s), id(n) {   }
        ~Worker() {   }
        void Set();
        void Show() const;
};

void Worker::Set()
{
    std::cout << "Enter worker's name: ";
    std::cin >> fullname;
    std::cout << "Enter worker's ID: ";
    std::cin >> id;
    while (std::cin.get() != '\n')
        continue;
}

void Worker::Show() const
{
    std::cout << "Name: " << fullname << std::endl;
    std::cout << "Employee ID: " << id << std::endl;
}
#endif

 

//14_3.cpp
#include "worker.h"
#include <iostream>

 
int main()
{
    const int LEN = 3;
    QueueTp<Worker *> q(LEN);
    int ct;
    for (ct = 0; ct < LEN; ct++)
    {
        std::cout << ct + 1 << ": \n";
        if(q.Push(new Worker)) q.rear()->Set();
    }
    std::cout << "dequeue now!" << std::endl;
    for (ct = 0; ct < LEN; ct++)
    {
        q.front()->Show();
        q.Pop();
    }
    return 0;
}

 

//question4

//personmi.h
#ifndef PERSONMI_H
#define PERSONMI_H
#include <string>
using std::string;

class Person
{
    private:
        string first_name;
        string last_name;
    protected:
        virtual void Get();
        virtual void Data();
    public:
        Person() : first_name("none"), last_name("none") {}
        Person(const std::string & fn, const std::string & ln) : first_name(fn), last_name(ln) {}
        ~Person() {}
        virtual void Show();
        virtual void Set();
};

class Gunslinger : virtual public Person
{
    private:
        int count;
        double ti;
    protected:
        void Get();
        void Data();
    public:
        Gunslinger() : Person(), count(0), ti(0) {}
        Gunslinger(const std::string & fn, const std::string & ln, int ct = 0, double t = 0) : Person(fn, ln), count(ct), ti(t) {}
        Gunslinger(const Person & ps, int ct = 0, double t = 0) : Person(ps), count(0), ti(t) {}
        ~Gunslinger() {}
        double Draw() {return ti;}
        void Show();
        void Set();
};

class Card
{
    private:
        static char * Card_n[4];
        int cn;
        int num;
    public:
        Card() : num(1), cn(0) {}
        Card(int c, int n) : cn(c), num(n) {}
        ~Card() {}
        void Show() const;
};

class PokerPlayer : virtual public Person
{
    protected:
        Card Draw();
        void Data();
    public:
        PokerPlayer() : Person() {}
        PokerPlayer(const std::string & fn, const std::string & ln) : Person(fn, ln) {}
        PokerPlayer(const Person & ps) : Person(ps) {}
        ~PokerPlayer() {}
        void Set();
        void Show();
};

class BadDude : public Gunslinger, public PokerPlayer
{
    protected:
        double Gdraw() {return Gunslinger::Draw();}
        Card Cdraw();
        void Data();
    public:
        BadDude() : Person(), Gunslinger(), PokerPlayer() {}
        BadDude(const std::string & fn, const std::string & ln, int ct = 0, double t = 0) : Person(), Gunslinger(fn, ln, ct, t), PokerPlayer() {}
        BadDude(const Person & ps, int ct = 0, double t = 0) : Gunslinger(ps, ct, t), PokerPlayer() {}
        BadDude(const Gunslinger & gs) : Person(gs), PokerPlayer() {}
        BadDude(const PokerPlayer & pp, int ct = 0, double t = 0) : Person(pp), Gunslinger(pp, ct, t) {} 
        ~BadDude() {}
        void Set();
        void Show();
};
#endif

//personmi.cpp
#include "personmi.h"
#include <iostream>
#include <cstdlib> 

using std::cout;
using std::endl;
using std::cin;

void Person::Get()
{
    cin >> first_name;
    cout << "Enter the last name: ";
    cin >> last_name;
}

void Person::Set()
{
    cout << "Enter the person's first name: ";
    Get();
}

void Person::Data()
{
    cout << "First name is: " << first_name << endl;
    cout << "Last name is: " << last_name << endl; 
}

void Person::Show()
{
    cout << "Category : Person\n";
    Data();
}

//char * Card_n[4] = {"Spade", "Heart", "Diamond", "Club"};

void Gunslinger::Get()
{
    cout << "Enter the gunslinger's time to hold the gun: ";
    cin >> ti;
    cin.get();
    cout << "Enter the num of nicking of his gun: ";
    cin >> count;
    cin.get();
}

void Gunslinger::Data() 
{
    cout << "Time to hold the gun: " << ti << endl;
    cout << "Num of nicking: " << count << endl;
}

void Gunslinger::Show() 
{
    cout << "Category : Gunslinger\n";
    Person::Data();
    Data();
}

void Gunslinger::Set()
{
    cout << "Enter the person's first name: ";
    Person::Get();
    Get();
}

char * Card::Card_n[4] = {"Spade", "Heart", "Diamond", "Club"};

void Card::Show() const
{
    cout << Card_n[cn] << " " << num << endl;
}

void PokerPlayer::Data()
{
    cout << "Card is: \n";
    Draw().Show();
}

void PokerPlayer::Set()
{
    cout << "Enter the PokerPlayer's first name: ";
    Person::Get();
}

void PokerPlayer::Show()
{
    cout << "Category : PokerPlayer\n";
    Person::Data();
    Data();

Card PokerPlayer::Draw()
{
    //srand((unsigned)time(NULL));
    return Card(rand()%3, rand()%52+1);
}

Card BadDude::Cdraw()
{
    return Card(rand()%3, rand()%52+1);
}

void BadDude::Data()
{
    cout << "Card is: \n";
    Cdraw().Show();
}

void BadDude::Set()
{
    cout << "Enter the BadDude's first name: ";
    Person::Get();
    Gunslinger::Get();
}

void BadDude::Show()
{
    cout << "Category : BadDude\n";
    Person::Data();
    Gunslinger::Data();
    Data();
}

//14_4.cpp
#include "personmi.h"
#include <iostream>
#include <cstring>
const int SIZE = 5;

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    using std::strchr;
    
    Person * persons[SIZE];
    int ct;
    for (ct = 0; ct < SIZE; ct++)
    {
        char choice;
        cout << "Enter the person category:\n"
             << "g: Gunslinger    p: PokerPlayer\n"
             << "b: BadDude       q: Quit\n";
        cin >> choice;
        while (strchr("gpbq", choice) == NULL)
        {
            cout << "Please enter a g, p, b or q: ";
            cin >> choice;
        }
        if (choice == 'q')
            break;
        switch(choice)
        {
            case 'g':    persons[ct] = new Gunslinger;
                         break;
            case 'p':    persons[ct] = new PokerPlayer;
                         break;
            case 'b':    persons[ct] = new BadDude;
                         break;
        }
        cin.get();
        persons[ct]->Set();
    }
    cout << "\nHere is the information:\n";
    int i;
    for(i = 0; i < ct; i++)
    {
        cout << endl;
        persons[i]->Show();
    }
    for (i = 0; i < ct; i++)
    {
        delete persons[i];
    }
    return 0;
}

//question5

//emp.h
#ifndef EMP_H
#define EMP_H
#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;

class abstr_emp
{
    private:
        std::string fname;
        std::string lname;
        std::string job;
    public:
        abstr_emp();
        abstr_emp(const std::string & fn, const std::string & ln, const std::string & j);
        virtual void ShowAll() const;
        virtual void SetAll();
        friend std::ostream & operator<<(std::ostream & os, const abstr_emp & e);
        //~abstr_emp(){} 
};

class employee : virtual 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();
};

class manager : virtual public abstr_emp
{
    private:
        int inchargeof;
    protected:
        int InChargeOf() const {return inchargeof;}
        int & InChargeOf() {return inchargeof;}
    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();
};

class fink : virtual public abstr_emp
{
    private:
        std::string reportsto;
    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();
};

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 fink & f, int ico);
        highfink(const manager & m, const std::string & rpo);
        highfink(const highfink & h);
        virtual void ShowAll() const;
        virtual void SetAll();
};

void abstr_emp::ShowAll() const
{
    cout << "First name: " << fname << endl;
    cout << "Last name: " << lname << endl;
    cout << "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 manager::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "Inchargeof is: " << inchargeof << endl;
}

void manager::SetAll()
{
    
    abstr_emp::SetAll();
    cout << "Enter inchargeof: ";
    cin >> inchargeof;
    cin.get();
}

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

void fink::SetAll()
{
    abstr_emp::SetAll();
    
    cout << "Enter the reportsto: ";
    cin >> reportsto;
}

void highfink::ShowAll() const
{
    manager::ShowAll();
    cout << "Reportsto is: " << fink::ReportsTo() << endl;
}

void highfink::SetAll()
{
    manager::SetAll();
    
    cout << "Enter the reportsto: ";
    std::string a;
    cin >> a; 
    fink::ReportsTo() = a;
}

void employee::ShowAll() const
{
    abstr_emp::ShowAll();
}

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

abstr_emp::abstr_emp() : fname("none"), lname("none"), job("none")
{
}

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


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

employee::employee() : abstr_emp()
{
}

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

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;
}

fink::fink() : abstr_emp(), reportsto("none")
{
}

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;
}

highfink::highfink() : abstr_emp(), manager(), fink()
{
}

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 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)
{
}

highfink::highfink(const highfink & h) : abstr_emp(h), manager(h), fink(h)
{
}
#endif

//14_5.cpp
#include <iostream>
using namespace std;
#include "emp.h"

int main()
{
    employee em("Trip", "Harris", "Thumper");
    cout << em << endl;
    em.ShowAll();
    manager ma("Amorphia", "Spindragon", "Nuancer", 5);
    cout << ma << endl;
    ma.ShowAll();
    
    fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
    cout << fi << endl;
    fi.ShowAll();
    highfink hf(ma, "Curly Kew");
    hf.ShowAll();
    cout << "Press a key for next phase:\n";
    cin.get();
    highfink hf2;
    hf2.SetAll();
    
    cout << "Using an abstr_emp * pointer:\n";
    abstr_emp * tri[4] = {&em, &fi, &hf, &hf2};
    for (int i = 0; i < 4; i++)
        tri[i]->ShowAll();
    
    return 0;
}

 

这道题在写的过程中踩了坑,忘了虚函数的实现要和定义放在一个文件中,也就是都放在.h文件里。

另外,修改部分代码后应全部重新编译,而不是直接编译运行,否则运行的还是之前修改前缓存的结果。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值