[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])。

浙公网安备 33010602011771号