C++ Primer Plus 第六版 第十四章 練習(xí)題參考答案


習(xí)題一
習(xí)題要求:使用包含關(guān)系,結(jié)合題目所給出類的方法提示,完成所有類方法的定義,并利用題目給出的測試程序測試
練習(xí)目標(biāo):了解并掌握對象的包含關(guān)系編程思想

//Wine.h
#ifndef WINE_H_
#define WINE_H_
#include<iostream>
#include<valarray>
#include<string>
using namespace std;

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 valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;

class Wine {
private:
    string s;
    PairArray p;
public:
    explicit Wine();
    explicit Wine(const char * l, int y, const int yr[], const int bot[]);
    ~Wine(){}
    explicit Wine(const char *l, int y);
    void GetBottles();
    string & Label();
    int sum() const { return p.second().sum(); };
    void Show() const;
};
#endif // !WINE_H_
//Wine.cpp
#include<iostream>
#include"Wine.h"

Wine::Wine()
{
    s = "";
    p.first() = p.second() =  0;
}

Wine::Wine(const char *l, int y, const int yr[], const int bot[])
{
    s = l;
    p.first() = ArrayInt(y);
    p.second() = ArrayInt(y);
    for (int i = 0; i < y; ++i)
    {
        p.first()[i] = yr[i];
        p.second()[i] = bot[i];
    }

}

Wine::Wine(const char * l, int y)
{
    s = l;
    p.first() = ArrayInt(y);
    p.second() = ArrayInt(y);
}

void Wine::GetBottles()
{
    cout << "enter "<< s <<" data for "<< p.first().size() <<" year(s): \n";
    for (int i = 0; i < (p.first().size()); i++)
    {
        cout << "Enter year: ";
        cin >> p.first()[i];
        cout << "Enter bottles for that years: ";
        cin >> p.second()[i];
    }
}

string & Wine::Label()
{
    return s;
}


 void Wine::Show() const
{
    cout << "Wine: " << s << endl;
    cout << "Year    Bottles" << endl;
    for (int i = 0; i < (p.first().size()); i++)
         cout << p.first()[i] << "    " << p.second()[i] << endl;
}
//main.cpp
#include <iostream>
#include"Wine.h"
int main()
{
    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); //store label,years
    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";
    system("pause");
    return 0;
}

習(xí)題二
題目要求:使用私有繼承機(jī)制完成習(xí)題一
練習(xí)目標(biāo):了解并掌握私有繼承關(guān)系編程思想

//Wine.h
#ifndef WINE_H_
#define WINE_H_
#include<iostream>
#include<valarray>
#include<string>
using namespace std;

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 valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;

class Wine :private string ,private PairArray
{
public:
    explicit Wine();
    explicit Wine(const char * l, int y, const int yr[], const int bot[]);
    ~Wine(){}
    explicit Wine(const char *l, int y);
    void GetBottles();
    string & Label();
    int sum() const { return PairArray::second().sum(); };
    void Show() const;
};
#endif // !WINE_H_
//Wine.cpp
#include<iostream>
#include"Wine.h"

Wine::Wine()
{
    string("");
    PairArray::first() = PairArray::second() =  0;
}

Wine::Wine(const char *l, int y, const int yr[], const int bot[])
{
    (string &)*this = l;
    PairArray::first() = ArrayInt(y);
    PairArray::second() = ArrayInt(y);
    for (int i = 0; i < y; ++i)
    {
        PairArray::first()[i] = yr[i];
        PairArray::second()[i] = bot[i];
    }

}
Wine::Wine(const char * l, int y)
{
    (string &)*this = l;
    PairArray::first() = ArrayInt(y);
    PairArray::second() = ArrayInt(y);
}

void Wine::GetBottles()
{
    cout << "enter "<< (const string &)*this <<" data for "<< PairArray::first().size() <<" year(s): \n";
    for (int i = 0; i < (PairArray::first().size()); i++)
    {
        cout << "Enter year: ";
        cin >> PairArray::first()[i];
        cout << "Enter bottles for that years: ";
        cin >> PairArray::second()[i];
    }
}
string & Wine::Label()
{
    return (string &) *this;
}
 void Wine::Show() const
{
    cout << "Wine: " << (const string &)*this << endl;
    cout << "Year    Bottles" << endl;
    for (int i = 0; i < (PairArray::first().size()); i++)
         cout << PairArray::first()[i] << "    " << PairArray::second()[i] << endl;
}

習(xí)題三
題目要求:使用第12章所定義的抽象數(shù)據(jù)類——隊列,將其轉(zhuǎn)換為模板類,并聲明一個指向本節(jié)程序清單14.12所定義的Worker 類的指針隊列,并利用隊列來測試。
練習(xí)目標(biāo):掌握模板類的定義以及其中靜態(tài)成員的初始化聲明;理解并掌握多重繼承的語法機(jī)制以及虛基類思想。

//worker.h
#ifndef WORKER_H_
#define WORKER_H_
#include<iostream>
#include<string>
using namespace std;

template<typename T>
class QueueTp
{
private:
    enum { Q_SIZE = 10 };
    struct Node { T item; struct Node * next; };
    Node *front;
    Node * rear;
    int items;
    int qsize;
public:
    QueueTp();
    ~QueueTp();
    bool isempty() const;
    bool isfull() const;
    int queuecount() const;
    bool enqueue(const T &item);
    T dequeue(T &item);
};
template <typename T>
QueueTp<T>::QueueTp()
{
    qsize = 0;
    front = rear = NULL;
    items = 0;
}
template<typename T>
QueueTp<T>::~QueueTp()
{
    Node *temp;
    while (front != NULL)
    {
        temp = front;
        front = front->next;
        delete temp;
    }
}
template <typename T>
bool QueueTp<T>::isempty() const
{
    return items == 0;
}
template <typename T>
bool QueueTp<T>::isfull() const
{
    return items == qsize;
}
template<typename T>
int QueueTp<T>::queuecount() const
{
    return items;
}
template<typename T>
bool QueueTp<T>::enqueue(const T &item)
{
    Node *add = new Node;
    add->item = item;
    add->next = NULL;
    items++;
    if (front == NULL)
        front = add;
    else 
        rear->next = add;
    rear = add;
    return true;
}
template<typename T>
T QueueTp<T>::dequeue(T &item)
{
    item = front->item;
    items--;
    Node *temp = front;
    front = front->next;
    delete temp;
    if (items == 0)
        rear = NULL;
    return item;
}

class Worker
{
private:
    string fullname;
    long id;
protected:
    virtual void Data() const;
    virtual void Get();
public:
    Worker() :fullname("no one"), id(0L) { }
    Worker(const string &s,long n):fullname(s),id(n) { }
    virtual ~Worker() = 0;
    virtual void Set() = 0;
    virtual void Show() const = 0;
};
class Waiter :virtual public Worker
{
private:
    int panache;
protected:
    void Data() const;
    void Get();
public:
    Waiter() :Worker(), panache(0) { }
    Waiter(const string &s, long n, int p = 0) : Worker(s, n), panache(p) { }
    Waiter(const Worker &wk, int p = 0) : Worker(wk), panache(p) { }
    void Set();
    void Show() const;
};
class Singer :virtual public Worker
{
protected:
    enum {other,alto,contralto,soprano,bass,baritone,tenor};
    enum {Vtype = 7};
    void Data() const;
    void Get();
private:
    static char * pv[Vtype];
    int voice;
public:
    Singer() :Worker(), voice(other) { }
    Singer(const string &s, long n, int v = other) :Worker(s, n), voice(v) { }
    Singer(const Worker &wk, int v = other) :Worker(wk), voice(v) {}
    void Set();
    void Show() const;
};
class SingingWaiter :public Singer, public Waiter
{
protected:
    void Data() const;
    void Get();
public:
    SingingWaiter() {}
    SingingWaiter(const string &s, long n, int p = 0, int v = other) : Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
    SingingWaiter(const Worker &wk, int p = 0, int v = other) :Worker(wk), Waiter(wk, p), Singer(wk, v) {}
    SingingWaiter(const Waiter &wk, int v = other) : Worker(wk), Waiter(wk), Singer(wk, v) {}
    SingingWaiter(const Singer &wt, int p = 0) : Worker(wt), Waiter(wt, p), Singer(wt) {}
    void Set();
    void Show() const;
};
#endif // !WORKER_H_


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

Worker::~Worker() {}
void Worker::Data() const
{
    cout << "Name:  " << fullname << endl;
    cout << "Employee ID: " << id << endl;
}
void Worker::Get()
{
    getline(cin, fullname);
    cout << "Enter worker's ID: ";
    cin >> id;
    while (cin.get() != '\n')
        continue;
}
void Waiter::Set()
{
    cout << "Enter waiter's name: ";
    Worker::Get();
    Get();
}
void Waiter::Show() const
{
    cout << "Category: waiter\n";
    Worker::Data();
    Data();
}
void Waiter::Data() const
{
    cout << "Panache rating: " << panache << endl;
}
void Waiter::Get()
{
    cout << "Enter waiter's panache rating: ";
    cin >> panache;
    while (cin.get()!= '\n')
        continue;
}
//Singer methods
char * Singer::pv[Singer::Vtype] = { "other","alto","contralto","soprano","bass","baritone","tenor" };
void Singer::Set()
{
    cout << "Enter singer's name: ";
    Worker::Get();
    Get();
}
void Singer::Show() const
{
    cout << "Category: singer\n";
    Worker::Data();
    Data();
}
void Singer::Data() const
{
    cout << "Vocal range: " << pv[voice] << endl;
}
void Singer::Get()
{
    cout << "Enter number for singer's vocal range:\n";
    int i;
    for (i = 0; i < Vtype; i++)
    {
        cout << i << ": " << pv[i] << " ";
        if (i % 4 == 3)
            cout << endl;
    }
    if (i % 4 != 0)
        cout << '\n';
    cin >> voice;
    while (cin.get() != '\n')
        continue;
}
void SingingWaiter::Data() const
{
    Singer::Data();
    Waiter::Data();
}
void SingingWaiter::Get()
{
    Waiter::Get();
    Singer::Get();
}
void SingingWaiter::Set()
{
    cout << "Enter singing waiter's name: ";
    Worker::Get();
    Get();
}
void SingingWaiter::Show() const
{
    cout << "Category: singing waiter:\n";
    Worker::Data();
    Data();
}

//main.cpp
#include <iostream>
#include<cstring>
#include"worker.h"
const int SIZE = 5;
int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    using std::strchr;
    Worker *q[SIZE];
    QueueTp<Worker *> w;
    int ct;
    for (ct = 0; ct < SIZE; ct++)
    {
        char choice;
        cout << "Enter the employee category:\n"
            << "w:waiter s:singer"
            << "t:sing waiter q:quit\n";
        cin >> choice;
        while (strchr("wstq", choice) == NULL)
        {
            cout << "Please enter a w,s,t,q: ";
            cin >> choice;
        }
        if (choice == 'q')
            break;
        switch (choice)
        {
        case 'w':   q[ct] = new Waiter;
                    w.enqueue(q[ct]);
            break;
        case 's':   q[ct] = new Singer;
                    w.enqueue(q[ct]);
            break;
        case 't':   q[ct] = new SingingWaiter;
                    w.enqueue(q[ct]);   
            break;
        }
        cin.get();
        q[ct]->Set();
    }       
    cout << "Here is your stuff:\n";
    while (!w.isempty())
    {
        cout << endl;
        for (int i = 0; i < ct; i++)
        {
            w.dequeue(q[i])->Show();
        }
        for (int i = 0; i < ct; i++)
            delete q[i];
    }
    cout << "Bye.\n";
    system("pause");
    return 0;
}


習(xí)題四
題目要求:給出題目所要求的類方法定義,并對類進(jìn)行測試。
練習(xí)目標(biāo):掌握多重繼承的語法機(jī)制以及虛基類思想。

//person.h
class Person
{
private:
    std::string fname;
    std::string lname;
public:
    Person();
    Person(std::string &f, std::string &l) :fname(f), lname(l) {}
    virtual ~Person() = 0;
    virtual void Set() = 0;
    virtual void Show() const = 0;
};
class Gunslinger : virtual public Person
{
private:
    int trace;
    double time;
public:
    Gunslinger() :Person(), trace(0),time(0) {}
    Gunslinger(std::string &f, std::string &l, int tr,double t) :Person(f, l), trace(tr),time(t) {}
    Gunslinger(const Person &p, int tr = 0,double t=0) :Person(p), trace(tr),time(t) {}
    double Draw() const { return time; };   
    void Show() const;
    void Set();
};
class PocketPlayer : virtual public Person
{
public:
    PocketPlayer():Person() {}
    PocketPlayer(std::string &f, std::string &l):Person(f, l) {}
    int Draw() const;
    void Set();
    void Show() const;
};
class BadDude :public Gunslinger, public PocketPlayer
{
public:
    BadDude(){}
    BadDude(std::string &f, std::string &l, int tr,double t) :Person(f, l), Gunslinger(f, l, tr, t), PocketPlayer(f, l) {}
    double Gdraw() const;
    int Cdraw();
    void Set() ;
    void Show() const;
};
//person.cpp
#include<iostream>
#include"person.h"

Person::Person()
{
    fname = lname = '\0';
}

Person::~Person(){}

void Person::Set()
{
    std::cout << "the first name: \n";
    std::getline(std::cin, fname);
    std::cout << "the last name: \n";
    std::getline(std::cin, lname);
}

void Person::Show() const
{
    std::cout << "Name: " << fname << " " << lname << std::endl;
}

void Gunslinger::Show() const
{
    Person::Show();
    std::cout << "Gun trace: " << trace << std::endl;
    std::cout << "Gun time: " << Draw() << std::endl;
}

void Gunslinger::Set()
{
    Person::Set();
    std::cout << "Please enter the trace and time of gun.\n";
    std::cout << "trace: \n";
    std::cin >> trace;
    std::cout << "time: \n";
    std::cin >> time;
}

int PocketPlayer::Draw() const
{
    return std::rand() % (52 - 1 + 1) + 1 ;
}

void PocketPlayer::Set()
{
    Person::Set();
}

void PocketPlayer::Show() const
{
    Person::Show();
    std::cout << "Poker value: " << Draw() << std::endl;
}

double BadDude::Gdraw() const
{
    return Gunslinger::Draw();
}

int BadDude::Cdraw()
{
    return PocketPlayer::Draw();
}

void BadDude::Set()
{
    Person::Set();
}

void BadDude::Show() const
{
    Person::Show();
    std::cout << "Poker value: " << PocketPlayer::Draw() << std::endl;
    std::cout << "Gun time: " << Gunslinger::Draw() << std::endl;
}
//main.cpp與第三題一致。

習(xí)題四
題目要求:給出題目所要求的類方法定義,并對類進(jìn)行測試。
練習(xí)目標(biāo):掌握多重繼承的初始化語法以及虛二義性。
注:本題是有缺陷的代碼,請再改進(jìn)

//emp.cpp
#include<iostream>
#include"emp.h"

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

abstr_emp::abstr_emp(const abstr_emp & e)
{
    fname = e.fname;
    lname = e.lname;
    job = e.job;
}

void abstr_emp::ShowAll() const
{
    std::cout << "name is: " << fname << " " << lname <<" \n";
    std::cout << "job is: " << job << std::endl;
}

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

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

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

void employee::SetAll()
{
    std::cout << "enter the employees' name: \n";
    abstr_emp::SetAll();
}

void manager::ShowAll() const
{
    abstr_emp::ShowAll();
    std::cout << "in charge of: " << inchargeof << std::endl;
}

void manager::SetAll()
{
    std::cout << "enter the manager's name: \n";
    abstr_emp::SetAll();
    std::cout << "enter the inchargeof: ";
    std::cin >> inchargeof;
}

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

void fink::SetAll()
{
    abstr_emp::SetAll();
    std::cout << "reports to: \n";
    std::cin >> reportsto;
}

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

void highfink::SetAll()
{
    manager::SetAll();
    fink::SetAll();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容