[C++ Primer Plus] 第10章、对象和类——(二)课后习题

1、

 account.h

#ifndef ACCOUNT_H_
#define ACCOUNT_H_

#include <string>
using namespace std;

class Account
{
private:
    string name_;     //姓名
    string number_;   //账号
    double money_;    //存款
public:
    //Account();
    Account(const string &na="",  const string &num="", double mon = 0.0);   
    void show();                  //显示
    void deposit(double cash);    //存款
    void withdraw(double cash);   //取款
};

#endif

 account.cpp

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

using namespace std;

//构造函数
/*
Account::Account()
{
    name_ = "";
    number_ = "";
    money_ = 0.0;
}
*/

Account::Account(const string &na,const string &num, double mon)
{
    name_ = na;
    number_ = num;
    if (mon < 0)
    {
        cout << "存款不得小于0!" << endl;
        money_ = 0;
    }
    else
        money_ = mon;
}

void Account::show()
{
    ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);//设置cout对象的一个标记,命令cout使用定点表示法
    streamsize prec = cout.precision(2);
    cout << "储户姓名:" << name_ << endl;
    cout << "储户账号:" << number_ << endl;
    cout << "存款:" << money_ << endl;
}

void Account::deposit(double cash)
{
    if (cash < 0)
    {
        cout << "存款金额不能小于0!" << endl;
    }
    else
    {
        money_ += cash;
        cout << "存款成功,目前您的存款为:" << money_ << endl;
    }
}

void Account::withdraw(double cash)
{
    if (cash < 0)
    {
        cout << "取款金额不能小于0!" << endl;
    }
    else if (cash>money_)
    {
        cout << "取款金额不能大于存款金额!" << endl;
    }
    else
    {
        money_ -= cash;
        cout << "取款成功,取走金额:" << cash << ' ' << "目前您的存款为:" << money_ << endl;
    }
}

 main.cpp

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

using namespace std;

int main()
{
    Account CBB("CBB", "1234w", 50000000.00);
    CBB.show();
    CBB.deposit(5.28);
    CBB.withdraw(200.28);

    system("pause");
    return 0;
}

 

 

 

 person.h

#ifndef PERSON_H_
#define PERSONT_H_

#include <string>

class Person
{
private:
    static const int LIMIT = 25;
    std::string lname;    //
    char fname[LIMIT];    //
public:
    Person() { lname = ""; fname[0] = '\0'; }
    Person(const std::string &ln, const char *fn = "Heyyou");
    void show() const;
    void formalshow() const;
};

#endif

 person.cpp

#include"person.h"
#include<iostream>
using namespace std;

Person::Person(const string &ln, const char *fn)
{
    lname = ln;
    strcpy_s(fname, fn);
}
void Person::show() const
{
    cout << fname << " " << lname << endl;
}
void Person::formalshow() const
{
    cout << lname << "," << fname << endl;
}

main.cpp

#include"person.h"
#include<iostream>
using namespace std;

int main()
{
    Person one;
    Person two("Smythecraft");
    Person three("Dimwiddy", "Sam");
    one.show();
    one.formalshow();
    two.show();
    two.formalshow();
    three.show();
    three.formalshow();

    system("pause");
    return 0;
}

 前两行的显示:one为空,没有输出,formalshow()有一个逗号

 

3.完成第9章的编程练习1,但要用正确的golf类声明替换那里的代码。用带合适参数的构造函数替换setgolf ( golf &, const char*, int), 以提供初始值。保留setgolf()的交互版本,但要用构造函数来实现它(例如,setgolf()的代码应该获得数据,将数据传递给构造函数来创建一个临时对象,并将其赋给调用对象,即*this)。

分析:与第9章第1题相比,只是部分函数参数和调用函数的格式变了。还有handicap变量和handicap函数不能重名。所以在这儿把int handicap改成int handicap_了。

 golf.h

//golf.h   --for pe9-1.cpp

const int Len = 40;
class Golf
{
private:
    char fullname[Len];
    int handicap_;
public:
    Golf() { fullname[0] = '\0'; handicap_ = 0; }
    Golf(const char *name, const int hc);
    int setgolf();
    void handicap(int hc);
    void showgolf();
};

golf.cpp

#include<iostream>
#include"golf.h"
using namespace std;

Golf::Golf(const char *name, const int hc)
{
    strcpy_s(fullname, name);           //注意:char型数组要用strcpy()
    handicap_ = hc;
}

int Golf::setgolf()
{
    cout << "Enter the fullname: ";
    cin.get(fullname, Len);
    if (fullname[0] == '\0')            //若姓名是空字符串则返回0
        return 0;
    cin.get();                            //跳过换行符
    cout << "Enter the handicap: ";
    cin >> handicap_;
    cin.get();//跳过换行符
    Golf g(fullname, handicap_);   //将数据传递给构造函数来创建一个临时对象
    *this = g;            //将临时对象赋给调用对象,即*this
    return 1;
}

void Golf::handicap(int hc)
{
    handicap_ = hc;
}

void Golf::showgolf()
{
    cout << "Golfer: " << fullname << endl;
    cout << "Handicap: " << handicap_ << endl;
}

main.cpp

#include <iostream>
#include"golf.h"
using namespace std;

const int cnt = 5;

int main()
{
    Golf ann("Ann Birdfree", 24);
    ann.showgolf();
    cout << endl;

    Golf andy[cnt];
    cout << "输入" << cnt << "名球队成员信息:" << endl;
    int i;
    for (i = 0; i<cnt; i++)
    {
        if (andy[i].setgolf() == 0)
            break;
    }
    cout << endl;
    for (int j = 0; j < i; j++)
    {
        andy[j].showgolf();
    }
    cout << endl;

    ann.handicap(88);
    ann.showgolf();

    system("pause");
    return 0;
}

输入空格时结束:

 

 4.完成第9章的编程练习4,但将Sales结构及相关的函数转换为一个类及其方法。用构造函数替换setSales ( sales&, double [] , int)函数。用构造函数实现setSales(Sales&)方法的交互版本。将类保留在名称空间SALES中。

 namesp.h

//namesp.h
namespace SALES
{
    const int QUARTERS = 4;
    class Sales
    {
    private:
        double sales[QUARTERS];
        double average;
        double max;
        double min;
    public:
        Sales();
        Sales(const double ar[], int n);
        void setSales();
        void showSales();
    };
}

namesp.cpp

#include<iostream>
#include"namesp.h"
using namespace std;

namespace SALES
{
    Sales::Sales()
    {
        sales[0] = sales[1] = sales[2] = sales[3] = average = max = min = 0;
    }

    //将4个或n个对象从数组ar中复制到s的sales成员,并计算和存储输入对象的平均值、最大值和最小值
    //sales的其余元素(如果有的话)设置为0
    Sales::Sales(const double ar[], int n)
    {
        double total = 0;
        for (int i = 0; i < QUARTERS; i++)
        {
            if (i >= n)
                sales[i] = 0;
            else
                sales[i] = ar[i];
            if (i == 0)
            {
                max = sales[i];
                min = sales[i];
            }
            else
            {
                if (sales[i] > max)
                    max = sales[i];
                if (sales[i] < min)
                    min = sales[i];
            }
            total += sales[i];
        }
        average = total / QUARTERS;
    }

    //以交互方式收集4个季度的销售额,将其存储在s的销售成员中,并计算和存储平均值、最大值和最小值
    void Sales::setSales()
    {
        double d[QUARTERS];
        for (int i = 0; i < QUARTERS; i++)
        {
            cout << "Enter the sales:" << endl;
            cin >> d[i];
        }
        Sales s(d, QUARTERS);   //在成员函数中调用构造函数是不会改变该对象的成员变量的值的,可以和上一题一样,将数据传递给构造函数来创建一个临时对象
        *this = s;      ////将临时对象赋给调用对象,即*this
    }

    //显示出来
    void Sales::showSales()
    {
        cout << "Sales:" << endl;
        for (int i = 0; i < QUARTERS; i++)
        {
            cout << sales[i] << endl;
        }
        cout << "Average: " << average << endl;
        cout << "Max: " << max << endl;
        cout << "Min: " << min << endl;
    }
}

main.cpp

#include<iostream>
#include"namesp.h"
using namespace std;

int main()
{
    using SALES::Sales;

    double d[4] = { 111.11, 222.22, 333.33, 444.44 };
    Sales s1(d, 4);
    s1.showSales();
    s1.setSales();
    s1.showSales();

    system("pause");
    return 0;
}

 

5.考虑下面的结构声明:
struct customer {

  char fullname[35];

  double payment;

};

编写一个程序,它从栈中添加和删除cunstomer结构(栈用Stack类声明表示)。每次customer结构被删除时,其payment的值都将被加入到总数中,并报告总数。注意:应该可以直接使用Stack类而不做修改;只需修改typedef声明,使Item的类型为customer,而不是unsigned long即可。

 stack.h

//stack.h
#ifndef STACK_H_    //如果没有定义SSTACK_H_
#define STACK_H_    //那么就定义STACK_H_

struct customer
{
    char fullname[35];
    double payment;
};

typedef customer Item;

class Stack        //类声明
{
private:
    enum { MAX = 10 };
    Item items[MAX];
    int top;
    int total;
public:
    Stack();    //默认构造函数
    bool isempty() const;
    bool isfull() const;
    bool push(const Item & item);//压栈
    bool pop(Item & item);//出栈
};

#endif // !STOCK00_H_  结束预定义

stack.cpp

#include "stack.h"
#include<iostream>
using namespace std;

//构造函数
Stack::Stack()   //创建一个空栈
{
    top = 0;
    total = 0;
}

bool Stack::isempty() const
{
    return top == 0;//top为0返回true,反之为false
}
bool Stack::isfull() const
{
    return top == MAX;
}
bool Stack::push(const Item &item)
{
    if (top<MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}
bool Stack::pop(Item &item)
{
    if (top>0)
    {
        item = items[--top];
        total += item.payment;
        cout << "目前收入:" << total << "" << endl;
        return true;
    }
    else
        return false;
}

main.cpp

#include<iostream>
#include<cctype>
#include "stack.h"
using namespace std;

void main()
{
    Stack st;
    char ch;
    Item po;
    cout << "按 A 添加一个顾客, 按 P 处理一个订单, 按 Q 退出.\n";
    while (cin >> ch&&toupper(ch) != 'Q')
    {
        while (cin.get() != '\n')//如果不是换行就继续
            continue;
        if (!isalpha(ch))//如果不是字母就继续
        {
            cout << '\a';
            continue;
        }
        switch (ch)
        {
        case 'A':
        case 'a':
            cout << "添加顾客姓名: ";
            cin .get(po.fullname,35).get();
            cout << "添加该顾客消费金额:";
            cin >> po.payment;
            if (st.isfull())//该方法判断:如果满了(top等于MAX)返回true,没满返回false
                cout << "已经存满10个顾客的订单!\n";
            else
                st.push(po);
            break;
        case 'P':
        case 'p':
            if (st.isempty())
                cout << "已经没有顾客订单了!\n";
            else
            {
                st.pop(po);
                cout << "顾客" << po.fullname << "的订单删除\n";

            }
            break;
        }
        cout << "按 A 添加一个顾客, 按 P 处理一个订单, 按 Q 退出.\n";
    }
    system("pause");
}

 

 

 6,h

//6.h
class Move        //类声明
{
private:
    double x;
    double y;
public:
    Move(double a = 0, double b = 0);
    void showmove()const;
    Move add(const Move &m)const;
    void reset(double a = 0, double b = 0);
};

6.cpp

#include "stack.h"
#include<iostream>
using namespace std;

Move::Move(double a, double b)
{
    x = a;
    y = b;
}
void Move::showmove()const
{
    cout << "x=" << x << " ,y=" << y << endl;
}
Move Move::add(const Move &m)const
{
    Move m1(this->x + m.x, this->y + m.y);
    return m1;
}
void Move::reset(double a, double b)
{
    x = a;
    y = b;
}

main.cpp

#include<iostream>
#include "6.h"
using namespace std;

void main()
{
    Move n,mm(2.5, 5.5);
    n.showmove();
    n=n.add(mm);
    n.showmove();
    n.reset();
    n.showmove();
    system("pause");
}

 

7.Plorg有这些特征。

数据:

①plorg的名称不超过19个字符;

②plorg有满意指数(CI),这是一个整数。

操作:

①新的plorg将有名称,其CI值为50;

②plorg的CI可以修改;

③plorg可以报告其名称和CI;

④plorg的默认名称为“Plorga”。

请编写一个Plorg类声明(包括数据成员和成员函数原型)来表示plorg,并编写成员函数的函数定义。然后编写一个小程序,以演示Plorg类的所有特性。

7.h

//7.h
class Plorg      //类声明
{
private:
    char name_[20];
    int ci_;
public:
    Plorg(char *na = "Plorga", int ci = 50);
    void setci(const int ci);
    void showplorg()const;
    void setname(const char *na);
};

7.cpp

#include "7.h"
#include<iostream>
using namespace std;

Plorg::Plorg(char *na, int ci)
{
    strcpy_s(name_, na);
    ci_ = ci;
}
void Plorg::setci(const int ci)
{
    ci_ = ci;
}
void Plorg::showplorg()const
{
    cout << "plorg的名称为:" << name_ << endl;
    cout << "plorg的满意指数(CI)为:" << ci_ << endl;
}
void Plorg::setname(const char *na)
{
    strcpy_s(name_, na);
}

main.cpp

#include<iostream>
#include "7.h"
using namespace std;

void main()
{
    Plorg p;
    p.showplorg();
    p.setname("Rick");
    p.setci(18);
    p.showplorg();
    system("pause");
}

 

 

 list.h

//头文件list.h  类定义
#ifndef LIST_H_
#define LIST_H_

typedef int Item;    //类型别名声明

class List
{
private:
    enum { MAX = 10 };
    Item items[MAX];
    int top;
public:
    List() { top = 0; }        //默认构造函数  
    bool isempty() const;      //确定是否为空 
    bool isfull() const;       //是否为满
    bool add(const Item item);    //添加数据项 
    void visit(void(*pf)(Item & item));  //显示每个数据项,并执行某种操作,具体是哪种,根据指针指向的函数而定 
};
#endif

list.cpp

#include "list.h"
#include<iostream>
using namespace std;

bool List::isempty() const
{
    return top == 0;
}
bool List::isfull() const
{
    return top == MAX;
}
bool List::add(const Item item)
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}
void List::visit(void(*pf)(Item & item))
{
    for (int i = 0; i < top; i++)
        (*pf)(items[i]);
}

main.cpp

#include<iostream>
#include "list.h"
using namespace std;

void print(Item &item);
void main()
{
    List t;
    cout << "列表是否为空?";
    if (t.isempty()==1)    //或if (t.isempty())
        cout << " 是空的" << endl;
    else
        cout << " 不是空的" << endl;
    cout << "列表是不是满了?";
    if (t.isfull())
        cout << " 是满的" << endl;
    else
        cout << " 不是满的" << endl;
    t.add(1);
    t.add(2);
    t.add(3);
    t.add(4);
    cout << "列表是否为空?" ;
    if (t.isempty())
        cout << " 是空的" << endl;
    else
        cout << " 不是空的" << endl;
    cout << "列表是不是满了?";
    if (t.isfull())
        cout << " 是满的" << endl;
    else
        cout << " 不是满的" << endl;
    void(*pf)(Item &it);
    pf = print;
    t.visit(pf);
    system("pause");
}

void print(Item &item)
{
    cout << item << endl;
}

 

void visit( void (*pf)(Item& m) ); 的意思是,visit函数中,使用函数指针pf作为参数。

在调用visit函数时,哪个函数名作为参数放在里面,那么pf指针就指向哪个函数(前提是类型相同)。

因为pf是函数指针,所以函数内部的pf(items[i])是将items[i]作为参数给pf指向的函数。例如当show函数作为参数给visit时,这里相当于show(items[i])。 

 

posted @ 2020-05-30 22:12  Fionaa  阅读(291)  评论(0)    收藏  举报