C++Primer Plus笔记——第十章 对象和类及课后编程练习答案
发布日期:2021-06-29 01:51:00 浏览次数:2 分类:技术文章

本文共 22826 字,大约阅读时间需要 76 分钟。

目录


本章小结

       面向对象编程强调的是程序如何表示数据。使用OOP方法解决编程问题的第一步是根据它程序之间的接口来描述数据,从而指定如何使用数据。然后,设计一个类来实现该接口。一般来说,私有数据成员存储信息,公有成员函数(又称为方法)提供访问数据的唯一途径。类将数据和方法组合成一个单元,其私有性实现数据隐藏。
       通常,将类声明分成两部分组成,这两部分通常保存在不冋的文件中。类声明(包括由函数原型表示的方法)应放到头文件中。定义成员函数的源代码放在方法文件中。这样便将接口描述与实现细节分开了。 从理论上说,只需知道公有接口就可以使用类。当然,可以查看实现方法(除非只提供了编译形式),但程序不应依赖于其实现细节,如知道某个值被存储为int。只要程序和  类只通过定义接口的方法进行通信,程序员就可以随意地对任何部分做独立的改进,而不必担心这样做会导致意外的不良影响。
       类是用户定义的类型,对象是类的实例。这意味着对象是这种类型的变量,例如由new按类描述分配的内存C++试图让用户定义的类型尽可能与标准类型类似,因此可以声明对象、指向对象的指针和对象数组。可以按值传递对象、将对象作为函数返回值、将一个对象赋给同类型的另一个对象。如果提供了构造函数,则在创建对象时,可以初始化对象。如果提供了析构函数方法,则在对象消亡后,程序将执行该函数。
       每个对象都存储自己的数据,而共享类方法。如果mr_object是对象名,try_me()是成员函数,则可以使用成员运算符句点调用成员函数:mr_object.try_me()。在OOP中,这种函数调用被称为将try_me消息发送给mr_object对象。在try_me()方法中引用类数据成员时,将使用mr_object对象相应的数据成员。同样,函数调用i_objet.try_me()将访问i_object对象的数据成员。
      如果希望成员函数对多个对象进行操作,可以将额外的对象作为参数传递给它。如果方法需要显式地引用调用它的对象,则可以使用this指针。由于this指针被设置为调用对象的地址,因此*this是该对象的别名。
       类很适合用于描述ADT(abstract data type,抽象数据类型)。公有成员函数接口提供了 ADT描述的服务,类的私有部分和类方法的代码提供了实现,这些实现对类的客户隐藏。

程序清单

创建一个Stock类(version 1)

10.1 stock00.h  Stock类的声明

//stock00.h -- Stock class interface//version 00#ifndef STOCK00_H_#define STOCK00_H_#include "stdafx.h"#include
class Stock //class declaration{private: std::string company; long shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val; }public: void acquire(const std::string & co, long n, double pr); void buy(long num, double price); void sell(long num, double price); void update(double price); void show();}; //note semicolon at the end#endif // !STOCK00_H_

 10.2 stock00.cpp  Stock类方法的实现

//stock00.cpp -- implementing the Stock class//version 00#include "stdafx.h"#include "stock00.h"#include
using namespace std;void Stock::acquire(const std::string & co, long n, double pr){ company = co; if (n < 0) { cout << "Number of shares can't be negative; " << company << " shares set to 0.\n"; shares = 0; } else shares = n; share_val = pr; set_tot();}void Stock::buy(long num, double price){ if (num < 0) { cout << "Number of shares purchased can't be negative. Transaction is aborted.\n"; } else { shares += num; share_val = price; set_tot(); }}void Stock::sell(long num, double price){ if (num < 0) { cout << "Number of shares sold can't be negative. Transaction is aborted.\n"; } else if (num > shares) { cout << "You can't sell more than you have! Transaction is aborted.\n"; } else { shares -= num; share_val = price; set_tot(); }}void Stock::update(double price){ share_val = price; set_tot();}void Stock::show(){ cout << "Company: " << company; cout << " Shares: " << shares << endl; cout << " Share Price: $" << share_val << endl; cout << " Total Worth: $" << total_val << endl;}

 10.3 usestock0.cpp  使用Stock类

// usestock0.cpp -- the client program// compile with stock00.cpp#include "stdafx.h"#include "stock00.h"#include
int main(){ Stock fluffy_the_cat; fluffy_the_cat.acquire("NanoSmart", 20, 12.50); fluffy_the_cat.show(); fluffy_the_cat.buy(15, 18.125); fluffy_the_cat.show(); fluffy_the_cat.sell(400, 20.00); fluffy_the_cat.show(); fluffy_the_cat.buy(300000, 40.125); fluffy_the_cat.show(); fluffy_the_cat.sell(300000, 0.125); fluffy_the_cat.show(); return 0;}

创建一个Stock类(version 2),增加了构造函数和析构函数

10.4 stock10.h  stock类的声明,添加了构造函数和析构函数

//stock10.h -- Stock class declaration with constructors destructor added//version 10#ifndef STOCK10_H_#define STOCK10_H_#include "stdafx.h"#include
class Stock //class declaration{private: std::string company; long shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val; }public: Stock();//default constructor Stock(const std::string & co, long n = 0, double pr = 0.0); ~Stock();//noisy destructor void buy(long num, double price); void sell(long num, double price); void update(double price); void show();}; //note semicolon at the end#endif // !STOCK10_H_

 10.5 stock10.cpp  stock类方法的实现,在这个版本中输出精度得到了统一

//stock10.cpp -- Stock class declaration with constructors destructor added//version 10#include "stdafx.h"#include "stock10.h"#include
using namespace std;//constructors (verbose versions)Stock::Stock(){ cout << "Default constructor called\n"; company = "no name"; shares = 0; share_val = 0.0; total_val = 0.0;}Stock::Stock(const std::string & co, long n /* = 0 */, double pr /* = 0.0 */){ cout << "Constructor using " << co << " called\n"; company = co; if (n < 0) { cout << "Number of shares can't be negative: " << company << " shares set to 0.\n"; shares = 0; } else shares = n; share_val = pr; set_tot();}//class destructorStock::~Stock(){ cout << "Bye. " << company << "!\n";}//other methodsvoid Stock::buy(long num, double price){ if (num < 0) { cout << "Number of shares purchased can't be negative. Transaction is aborted.\n"; } else { shares += num; share_val = price; set_tot(); }}void Stock::sell(long num, double price){ if (num < 0) { cout << "Number of shares sold can't be negative. Transaction is aborted.\n"; } else if (num > shares) { cout << "You can't sell more than you have! Transaction is aborted.\n"; } else { shares -= num; share_val = price; set_tot(); }}void Stock::update(double price){ share_val = price; set_tot();}void Stock::show(){ ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield); streamsize prec = cout.precision(3);//set format to #.### cout << "Company: " << company; cout << " Shares: " << shares << endl; cout << " Share Price: $" << share_val << endl; cout.precision(2);//set format to #.## cout << " Total Worth: $" << total_val << endl; //restore original format cout.setf(orig, ios_base::floatfield); cout.precision(prec);}

10.6 usestock1.cpp  使用stock类

//usestock1.cpp -- using the Stock class//compile with stock10.cpp#include "stdafx.h"#include "stock10.h"#include
int main(){ using namespace std; cout << "Using constructors to create new objects\n"; Stock stock1("NanoSmart", 12, 20.0); stock1.show(); Stock stock2 = Stock("Boffo Objects", 2, 2.0); stock2.show(); cout << "Assing stock1 to stock2:\n"; stock2 = stock1; cout << "Listing stock1 and stock2:\n"; stock1.show(); stock2.show(); cout << "Using a constructor to reset an object\n"; stock1 = Stock("Nifty Foods", 10, 50.0); cout << "Revised stock1:\n"; stock1.show(); cout << "Done\n"; return 0;}

创建一个Stock类(version 3),使用了*this指针

 10.7 stock20.h 添加了新方法topval()并使用了*this指针

//stock20.h -- sugmented version#ifndef STOCK20_H_#define STOCK20_H_#include 
class Stock{private: std::string company; int shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val; }public: Stock(); Stock(const std::string & co, long n = 0, double pr = 0.0); ~Stock(); void buy(long num, double price); void sell(long num, double price); void update(double price); void show() const; const Stock & topval(const Stock & s) const;};#endif // !STOCK20_H_

10.8 Stock类的实现,使用了*this指针 

//stock20.cpp -- augmented version//version 20#include "stdafx.h"#include "stock20.h"#include 
using namespace std;//constructors (verbose versions)Stock::Stock(){ company = "no name"; shares = 0; share_val = 0.0; total_val = 0.0;}Stock::Stock(const std::string & co, long n, double pr){ company = co; if (n < 0) { cout << "Number of shares can't be negative: " << company << " shares set to 0.\n"; shares = 0; } else shares = n; share_val = pr; set_tot();}//class destructorStock::~Stock(){}//other methodsvoid Stock::buy(long num, double price){ if (num < 0) { cout << "Number of shares purchased can't be negative. Transaction is aborted.\n"; } else { shares += num; share_val = price; set_tot(); }}void Stock::sell(long num, double price){ if (num < 0) { cout << "Number of shares sold can't be negative. Transaction is aborted.\n"; } else if (num > shares) { cout << "You can't sell more than you have! Transaction is aborted.\n"; } else { shares -= num; share_val = price; set_tot(); }}void Stock::update(double price){ share_val = price; set_tot();}void Stock::show() const{ ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield); streamsize prec = cout.precision(3);//set format to #.### cout << "Company: " << company; cout << " Shares: " << shares << endl; cout << " Share Price: $" << share_val << endl; cout.precision(2);//set format to #.## cout << " Total Worth: $" << total_val << endl; //restore original format cout.setf(orig, ios_base::floatfield); cout.precision(prec);}const Stock & Stock::topval(const Stock & s) const { if (s.total_val > total_val) return s; else return *this;}

10.9 使用stock类建立对象数组 

//usestock2.cpp -- using the Stock class//compile with stock20.cpp#include "stdafx.h"#include "stock20.h"#include 
const int STKS = 4;int main(){ using namespace std; Stock stocks[STKS] = { Stock("NamoSmart",12,20.0), Stock("Boffo Objects",200,2.0), Stock("Monolithic Obelisks",130,3.25), Stock("Fleep Enterprises",60,6.5) }; cout << "Stock holdings:\n"; int st; for (st = 0; st < STKS; st++) stocks[st].show(); const Stock *top = &stocks[0]; for (st = 1; st < STKS; st++) top = &top->topval(stocks[st]); cout << "\nMost valuable holding:\n"; top->show(); return 0;}

创建一个抽象数据类型(ADT)--stack类

 10.10 stack.h stack类的声明,stack(栈)是一种抽象数据类型(ADT)

//stack.h -- class definition for the stack ADT#ifndef STACK_H_#define STACK_H_typedef unsigned long Item;class  Stack{private:	enum { MAX = 10 };	Item items[MAX];	int top;public:	Stack();	bool isempty() const;	bool isfull() const;	bool push(const Item & item);	bool pop(Item & item);};#endif

10.11  stack类方法的实现

//stack.cpp -- Stack member functions#include "stdafx.h"#include "stack.h"Stack::Stack(){	top = 0;}bool Stack::isempty() const {	return top == 0;}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];		return true;	}	else		return false;}

10.12 使用stack类

//stacker.cpp -- testing the Stack class#include "stdafx.h"#include "stack.h"#include 
#include
int main(){ using namespace std; Stack st; char ch; unsigned long po; cout << "Please enter A to add a purchase order,\nP to process a PO ,or Q to quit.\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 << "Enter a PO number to add: "; cin >> po; if (st.isfull()) cout << "stack already full\n"; else st.push(po); break; case 'P': case 'p': if (st.isempty()) cout << "stack already empty\n"; else { st.pop(po); cout << "PO #" << po << " popped\n"; } break; } cout << "Please enter A to add a purchase order,\n" << "p to process a PO, or Q to quit.\n"; } cout << "Bye\n"; return 0;}

课后编程习题答案

习题1

//bankaccount.h#ifndef BANKACCOUNT_H_#define BANKACCOUNT_H_#include 
class BankAccount{ private: std::string name; std::string acctnum; double balance;public: BankAccount(const std::string & client, const std::string & num, double bal=0.0); void show() const; void deposit(double cash); void withdraw(double cash);};#endif//bankaccount.cpp#include
#include "bankaccount.h"BankAccount::BankAccount(const std::string & client, const std::string & num, double bal){ name = client; acctnum = num; balance = bal;} void BankAccount::show()const{ using std::cout; using std::endl; cout << "Client: " << name << endl; cout << "Account Number: " << acctnum << endl; cout << "Balance: " << balance << endl;} void BankAccount::deposit(double cash){ if (cash >= 0) balance += cash; else std::cout << "Illegal transaction attempted";} void BankAccount::withdraw(double cash){ if (cash < 0) std::cout << "Illegal transaction attempted"; else if (cash <= balance) balance -=cash; else std::cout << "Request denied due to insufficient funds.\n";} //main.cpp#include
#include "bankaccount.h"int main(){ BankAccount ba("Kermit", " croak322", 123.00); ba.show(); ba.deposit(20); ba.show(); ba.withdraw(300); ba.show(); ba.withdraw(23); ba.show(); return 0;}

习题2

//person.h#ifndef PERSON_H_#define PERSON_H_#include 
class Person{ private: static const int LIMIT=25; std::string lname; char fname[LIMIT];public: Person() {lname=""; fname[0]='\0';} //#1 Person(const std::string &ln, const char * fn="Heyyou"); //#2 // the following methods display lname and fname void Show() const; // firstname lastname format void FormalShow() const; // lastname, firstname format};#endif//person.cpp#include
#include
#include "person.h"Person::Person(const std::string &ln, const char * fn){ lname = ln; strcpy(fname, fn);} void Person::Show() const{ using std::cout; using std::endl; cout << "The people's name is " << fname << " "<< lname << endl;}void Person::FormalShow() const{ using std::cout; using std::endl; cout << "The people's name is " << lname << ", "<< fname <
#include "person.h"int main(){ using std::cout; using std::endl; Person one; Person two("Smythecraft"); Person three("Dimwiddy", "Sam"); one.Show(); one.FormalShow(); cout << endl; two.Show(); two.FormalShow(); cout << endl; three.Show(); three.FormalShow(); cout << endl; return 0;}

习题3

//golf.h#ifndef GOLF_H_#define GOLF_H_class Golf{private:    static const int Len = 40;    char fullname[Len];    int handicap;public:    Golf();    Golf(const char * name, int hc);    const Golf & setgolf(const Golf & g);    void showgolf() const;};#endif//golf.cpp#include 
#include
#include "golf.h"Golf::Golf(){ strcpy(fullname, "No Name"); handicap = 0;} Golf::Golf(const char *name, int hc){ strcpy(fullname, name); handicap = hc;} const Golf &Golf::setgolf(const Golf &g){ strcpy(fullname, g.fullname); handicap = g.handicap; return *this;} void Golf::showgolf() const{ std::cout << "Golfer: " << fullname << "\n"; std::cout << "Handicap: " << handicap << "\n\n";} //main#include
#include "golf.h"int main(){ Golf golger1("Ann Birdfree", 5); golger1.showgolf(); Golf golger2; golger2.setgolf(golger1); golger2.showgolf(); return 0;}

习题4

//sale.h#ifndef SALE_H_#define SALE_H_namespace SALES{     const int QUARTERS = 4;    class Sales    {    private:        double sales[QUARTERS];        double average;        double max;        double min;    public:        Sales(); // default constructor        // copies the lesser of 4 or n items from the array ar        // to the sales member of s and computes and stores the        // average, maximum, and minimum values of the entered items;        // remaining elements of sales, if any, set to 0        Sales(const double ar[], int n);        // gathers sales for 4 quarters interactively, stores them        // in the sales member of s and computes and stores the        // average, maximum, and minimum values        void setSales();        // display all information in structure s        void showSales() const;    };} #endif//sale.cpp#include 
#include "sale.h"namespace SALES{ using std::cout; using std::cin; using std::endl; static double calaverage(double arr[], unsigned arrSize) { double sum = 0; for (int i=0; i
arr[i]) min = arr[i]; } return min; } Sales::Sales() { min = 0; max = 0; average = 0; for (int i = 0; i < QUARTERS; i++) sales[i] =0; } Sales::Sales(const double ar[], int n) { unsigned times = n < QUARTERS ? (unsigned)n:QUARTERS; for (int i=0; i
> sales[i]; } *this = Sales(sales, QUARTERS); } void Sales::showSales() const { cout << "sales: "; for (int i=0; i
#include "sale.h"using namespace std;int main (){ using namespace SALES; double salesList[] = {12.2, 11.16, 10.61, 16.24, 11.53}; Sales salesBook(salesList, sizeof(salesList)/sizeof(salesList[0])); salesBook.showSales(); Sales salesPen; salesPen.setSales(); salesPen.showSales(); return 0;}

习题5

//stack.h#ifndef STACK_H_#define STACK_H_struct customer{    char fullname[35];    double payment;};typedef customer Item;class Stack{private:    enum {MAX = 10};    Item items[MAX];    int top;public:    Stack();    bool isempty() const;    bool isfull() const;    // push() returns false if stack already is full, true otherwise    bool push(const Item & item); // add item to stack    // pop() returns false if stack already is empty, true otherwise    bool pop(Item & item); // pop top into item};#endif//stack.cpp#include 
#include "stack.h"Stack::Stack(){ top = 0;}bool Stack::isempty() const{ return top == 0;} bool Stack::isfull() const{ return top == MAX;} bool Stack::push(const Item &item){ if (top
0) { item = items[--top]; return true; } else return false;} //main.cpp#include
#include
#include "stack.h"void get_customer(customer & cu);int main(){ using namespace std; Stack st; customer temp; double payment = 0; char ch; cout << "Please enter A to add a customer,\n" << "P to process a customer, and Q to quit.\n"; while (cin >> ch && (ch = toupper(ch)) != 'Q') { while (cin.get() != '\n') continue; if (ch != 'A' && ch != 'P') { cout << "Please respond A, P or Q: "; continue; } switch (ch) { case 'A': if (st.isfull()) cout << "stack already full\n"; else { get_customer(temp); st.push(temp); } break; case 'P': if (st.isempty()) cout << "stack is empty\n"; else { st.pop(temp); payment += temp.payment; cout << temp.fullname << " processed. "; cout << "Payments now total $" << payment << "\n"; } break; } cout << "Please enter A to add a customer,\n" << "P to process a customer, and Q to quit.\n"; } cout << "Done!\n"; return 0;}void get_customer(customer &cu){ using namespace std; cout << "Enter customer name: "; cin.getline(cu.fullname, 35); cout << "Enter customer payment: "; cin >> cu.payment; while (cin.get() != '\n') continue;}

习题6

//move.h#ifndef MOVE_H_#define MOVE_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;    //this function adds x of m to x of invoking object to get new x    //add y of m to y of invoking object to get new y, creates a new    //move object initialized to new x,y values and returns it    void reset(double a = 0,double b = 0);};#endif//move.cpp#include 
#include "move.h"Move::Move(double a, double b){ x = a; y = b;} void Move::showMove() const{ std::cout << "x = " << x << ", y = " << y << "\n";} Move Move::add(const Move &m) const{ Move temp; temp.x = x + m.x; temp.y = y + m.y; return temp;} void Move::reset(double a, double b){ x = a; y = b;} //main#include
#include "move.h"int main(){ using std::cout; using std::endl; Move move1(4,5); Move move2(2,1); Move move3; cout << "The number in move1 is:\n"; move1.showMove(); cout << "The number in move2 is:\n"; move2.showMove(); move3 = move2.add(move1); cout << "The number in move3 is :\n"; move3.showMove(); cout << "move1+move2, now move2's number is :\n"; move2.showMove(); cout << "After move1 + move2,now move1's number is :\n"; move1.showMove(); move1.reset(); cout << "After reset move1,now move1's number is:\n"; move1.showMove(); return 0;}

习题7

//plorg.cpp#ifndef PLORG_H_#define PLORG_H_class Plorg{ private:    char name[20];    int CI;public:    Plorg();    Plorg(char * na, int n = 50);    void resetCI(int n);    void showplorg() const;};#endif//plorg.cpp#include 
#include
#include "plorg.h"Plorg::Plorg(){ strcpy(name, "Plorga"); CI = 0;} Plorg::Plorg(char *na, int n){ strcpy(name, na); CI = n;} void Plorg::resetCI(int n){ CI = n;} void Plorg::showplorg() const{ std::cout << " The plorg's name is " << name << "\n" <<"The CI is "<< CI <
#include "plorg.h"int main(){ using namespace std; Plorg plorg1; plorg1.showplorg(); Plorg plorg2("heyyroup", 31); plorg2.showplorg(); plorg1.resetCI(41); plorg1.showplorg(); return 0;}

习题8

//list.h#ifndef LIST_H_#define LIST_H_const int TSIZE = 50;struct film{     char title[TSIZE];    int rating;};typedef struct film Item;const int LISTMAX = 10;class List{ private:    Item items[LISTMAX];    int count;public:    List();    bool isempty();    bool isfull();    int itemcount();    bool additem(Item item);    void visit(void (*pf)(Item &));};#endif//list.cpp#include "list.h"List::List(){ count = 0;} bool List::isempty(){     return count == 0;} bool List::isfull(){     return count == LISTMAX;} int List::itemcount(){    return count;} bool List::additem(Item item){     if (count == LISTMAX)        return false;    else        items[count++] = item;    return true;} void List::visit(void (*pf)(Item &)){     for (int i=0; i
#include
#include "list.h"void showfilm(Item & item);int main(){ using namespace std; List movies; Item temp; if (movies.isfull()) { cout << "No more room in list! Bye!\n"; exit(1); } cout << "Enter first movie title:\n"; while (cin.getline(temp.title, TSIZE) && temp.title[0] != '\0') { cout << "Enter your rating <1-10>: "; cin >> temp.rating; while (cin.get() != '\n') continue; if (movies.additem(temp) == false) { cout << "List already is full!\n"; break; } if (movies.isfull()) { cout << "You have filled the list.\n"; break; } cout << "Enter next movie title (empty line to stop):\n"; } if (movies.isempty()) cout << "No data entered."; else { cout << "Here is the movie list:\n"; movies.visit(showfilm); } cout << "Bye!\n"; return 0;} void showfilm(Item &item){ std::cout << "Movie: "<< item.title << "Rating: "<< item.rating << std::endl;}

 

转载地址:https://blog.csdn.net/yukinoai/article/details/82908657 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C++Primer Plus笔记——第十一章 使用类及课后编程练习答案
下一篇:C++Primer Plus笔记——第九章 内存模型和名称空间及编程练习答案

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月07日 07时31分26秒