[C++ Primer Plus] 第10章、對象和類(二)課後習題

1.

bank.hios

#include <string>
using namespace std;

class BankAccount        
{
private:
    std::string m_name;//如果不用命名空間的話,就須要加std::
    string m_id;
    double m_money;
public:
    BankAccount();
    BankAccount(const string & name,const string & id,double money=0.0);
    void show() const;
    void add(double money);
    void sub(double money);
};    

bank.cpp編程

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

//構造函數
BankAccount::BankAccount(){
    m_name = "";  
    m_id = "";  
    m_money = 0.0;  
}
BankAccount::BankAccount(const string & name,const string & id,double money){
    m_name = name;  
    m_id = id;  
    m_money = money;  
}

void BankAccount::show() const{
    ios_base::fmtflags orig=cout.setf(ios_base::fixed,ios_base::floatfield);//設置cout對象的一個標記,命令cout使用定點表示法
    streamsize prec=cout.precision(2);
    cout<< "Name: " << m_name << "    ID: " << m_id << "    Money: " << m_money << endl; //由於bank.h中已經聲明瞭命名空間,因此不須要加std::
}
void BankAccount::add(double money){
    m_money += money;  
}
void BankAccount::sub(double money){
    m_money -= money;
}

main.cpp小程序

#include "bank.h"

void main(){
    BankAccount a("MR.Zhang","20135908",8888888.88);
    a.show();
    a.add(88888.88);
    a.show();
    a.sub(88888.88);
    a.show();
    system("pause");
}


 

//person.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;  
};  

//person.cpp
#include <iostream>
#include "Person.h"

Person::Person(const std::string & ln, const char *fn)  
{  
    lname = ln;  
    strncpy_s(fname, fn ,24);  //fname的長度爲25 
}  
void Person::Show() const  
{  
    std::cout << fname << " " << lname << std::endl;  
}  
  
void Person::FormalShow() const  
{  
    std::cout << lname << ", " << fname << std::endl;  
}  

//main.cpp
#include "person.h"

void main(){
    Person one;  
    Person two("Smythecraft");  
    Person three("Dimwiddy", "Sam");  
    one.Show();  
    one.FormalShow();  
    two.Show();  
    two.FormalShow();  
    three.Show();  
    three.FormalShow(); 
    system("pause");
}

前兩行的顯示:one爲空,沒有輸出,FormalShow有一個逗號緩存


3.完成第9章的編程練習1,但要用正確的golf類聲明替換那裏的代碼。用帶合適參數的構造函數替換setgolf ( golf &, const char*, int), 以提供初始值。保留setgolf()的交互版本,但要用構造函數來實現它(例如,setgolf()的代碼應該得到數據,將數據傳遞給構造函數來建立一個臨時對象,並將其賦給調用對象,即*this)。函數

4.完成第9章的編程練習4,但將Sales結構及相關的函數轉換爲一個類及其方法。用構造函數替換setSales ( sales&, double [] , int)函數。用構造函數實現setSales(Sales&)方法的交互版本。將類保留在名稱空間SALES中。post

這兩題參考http://blog.csdn.net/qq20004604/article/details/50540039  或者   http://blog.csdn.net/acm_yuuji/article/details/47374799ui


 

5.考慮下面的結構聲明:
struct customer {this

  char fullname[35];spa

  double payment;.net

};

編寫一個程序,它從棧中添加和刪除cunstomer結構(棧用Stack類聲明表示)。每次customer結構被刪除時,其payment的值都將被加入到總數中,並報告總數。注意:應該能夠直接使用Stack類而不作修改;只需修改typedef聲明,使Item的類型爲customer,而不是unsigned long便可。

//stack.h
struct customer{
    char fullname[35];
    double payment;
};
typedef customer Item;

class Stack        //類聲明
{
private:
    double total; 
    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);//出棧
};    

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

//構造函數
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;  
        std::cout << "總共已取出" << total << "" << std::endl;  
        return true;
    }else
        return false;
}

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

void main(){
    cout.setf(ios_base::fixed);  
    cout.precision(2);  //設置輸出保留兩位小數
    Stack st;//建立對象儲物櫃  
    customer one;
    char ch;
    cout<<"Enter A to save money, P to withdraw money, 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':
            if(st.isfull())//該方法判斷:若是滿了(top等於MAX)返回true,沒滿返回false
                cout<<"Stack already full\n";
            else{
                cout << "請輸入存錢的人的名字:";  
                cin.getline(one.fullname,34);  
                cout << "請輸入要存多少錢:";  
                cin >> one.payment; 
                cin.sync(); //清除輸入緩存,防止干擾  
                if (st.push(one))  
                    cout << "存放成功!" << one.fullname << " 共計 " << one.payment << " 元錢已經被存進來啦!" << endl;  
                else  
                    cout << "因爲某種未知的緣由,存放失敗了。。。。" << endl;  
            }
            break;
        case 'P':
        case 'p':
            if(st.isempty())
                cout<<"Stack already empty\n";
            else{
                st.pop(one);
            }
            break;
        }
        cout<<"Enter A to save money, P to withdraw money, Q to quit.\n";
    }
    system("pause");
}


//1.h
class Move  
{  
private:  
    double x;  
    double y;  
public:  
    Move(double a = 0, double b = 0);   //set x,y to a,b  
    void showmove()const;   //shows current x,y values  
    Move add(const Move & m) const; //這個函數將被調用對象m的x和y值與本身的x,y值相加,並獲得2個新值,而後建立一個使用新的x、y值的move對象,並將增長後的x、y值賦給她,而後將這個新對象做爲返回值  
    void reset(double a = 0, double b = 0); //resets x,y to a,b  
};  

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

Move::Move(double a, double b){
    x = a;  
    y = b; 
}

void Move::showmove()const{
    std::cout << "x = " << x << ", y = " << y << std::endl;  
}

Move Move::add(const Move & m) const{
    Move q(this->x + m.x, this->y + m.y);  
    return q;  
}

void Move::reset(double a , double b ){
    x = a;  
    y = b; 
}

//main.cpp
#include<iostream>
#include "1.h"

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


7.Betelgeusean plorg有這些特徵。

數據:

①plorg的名稱不超過19個字符;

②plorg有滿意指數(CI),這是一個整數。

操做:

①新的plorg將有名稱,其CI值爲50;

②plorg的CI能夠修改;

③plorg能夠報告其名稱和CI;

④plorg的默認名稱爲「Plorga」。

請編寫一個Plorg類聲明(包括數據成員和成員函數原型)來表示plorg,並編寫成員函數的函數定義。而後編寫一個小程序,以演示Plorg類的全部特性。

//1.h
class Plorg  
{  
private:  
    char m_name[20];  
    int  m_CI;  
public:  
    Plorg(char * name = "Plorga", int CI = 50);  
    void show()const;   
    void setName(const char *name);  
    void setCI(const int CI);
};  

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

Plorg::Plorg(char * name, int CI){
    strncpy_s(m_name, name,19);  
    m_CI = CI;  
}
       
void Plorg::setName(const char *name){
    strncpy_s(m_name, name,19);  
} 
void Plorg::setCI(const int CI){
    m_CI = CI; 
}
void Plorg::show()const{
    std::cout << "name = " << m_name << ", CI = " << m_CI << std::endl;  
}

//main.cpp
#include<iostream>
#include "1.h"

void main(){
    Plorg p;
    p.show();
    p.setName("Jany");
    p.setCI(49);
    p.show();
    system("pause");
}


//list.h
#include <stdlib.h>    //包含NULL的定義
typedef int Item;  
  
class List  
{  
private:  
    static const int LIMIT  = 5;  
    Item items[LIMIT];  
    int top;  
public:  
    List() { top = 0; }   //默認構造函數  
    bool push(const Item); //添加數據項  
    bool isempty()const;    //肯定是否爲空  
    bool isfull()const;        //是否爲滿  
    void visit(void(*pf)(Item &m)); //顯示每一個數據項,並執行某種操做,具體是哪一種,根據指針指向的函數而定 
};  

//list.cpp
#include "List.h"  
  
bool List::push(const Item item)  
{  
    if (isfull() == true)  
        return false;  
    items[top++] = item;  
    return true;  
}  
  
bool List::isempty() const  
{  
    return top == 0 ? true : false;  
}  
  
bool List::isfull() const  
{  
    return top == LIMIT ? true : 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"

void Print(Item &item)  
{  
    std::cout << item << std::endl;  
} 
void main(){
    List l;  
    l.push(1);  
    l.push(2);  
    l.push(3);  
    l.push(4);  
    if(l.isempty())
        std::cout << "isEmpty? " << "Empty" << std::endl;
    else
        std::cout << "isEmpty? " << "Not Empty" << std::endl;
    if(l.isfull())
        std::cout << "isFull? " << "Full" << std::endl;
    else
        std::cout << "isFull? " << "Not Full" << std::endl;
    void(*pf)(Item &item);  
    pf = Print;  //或者    void(*pf)(Item &item) = Print
    l.visit(pf); 
    system("pause");
}

總結:

①在類中以函數指針做爲參數的時候,糾結了好久,查了別人的答案才明白。

例如:void visit( void (*pf)(Item& m) );

這個的意思是,visit函數中,使用函數指針pf做爲參數。

在調用visit函數時,哪一個函數名做爲參數放在裏面,那麼pf指針就指向哪一個函數(前提是類型相同)。

由於指針做爲參數,因此參數有點相似( char* pa)這樣的意思,char*表示pa是char類型的指針,但不是說char*是參數,因此函數指針做爲參數時,重點是pf,而不是外面那個修飾pf的。

可使用typedef void (*PP)(Item &m);將PP做爲這個的別名,因而能夠改成void visit(PP pf);這樣。

由於沒把函數指針學透,糾結了好久,寫完代碼纔想明白。

由於pf是函數指針,因此函數內部的pf(items[i])是將items[i]做爲參數給pf指向的函數。例如當show函數做爲參數給visit時,這裏至關於show(items[i])。

相關文章
相關標籤/搜索