C.Primer.Plus(第六版)第13章 编程练习

来源:互联网 发布:美丽中国网络知识竞赛 编辑:程序博客网 时间:2024/05/16 11:12

//13.1

//cd.h --- base class#ifndef CD__H__#define CD__H__class Cd{private:    char performers[50];//演员    char label[20];//标签    int selections;    double playtime;public:    Cd(char* s1,char* s2,int n,double x);    //Cd(const Cd & d);    Cd();    virtual ~Cd(){}    virtual void Report() const;    virtual Cd & operator=(const Cd & d);};class Classic : public Cd{private:    char works[20];public:    Classic(char* s1,char* s2,char* s3,int n,double x);    Classic();    virtual ~Classic(){}    virtual Classic & operator=(const Classic & c);};#endif
//classic.cpp#include <iostream>#include "cd.h"Cd::Cd(char* s1,char* s2,int n,double x){     strcpy(performers,s1);     strcpy(label,s2);     selections = n;     playtime = x;}//Cd(const Cd & d);Cd::Cd(){    strcpy(performers,"NULL");     strcpy(label,"NULL");     selections = 0;     playtime = 0.0;}void Cd::Report() const{    std::cout<<"The performers is "<<performers<<" ,and the label is "        <<label<<" ,the selections is "<<selections        <<" ,the playtime is "<<playtime<<std::endl;}Cd & Cd::operator=(const Cd & d){    if(this == &d)        return *this;    strcpy(performers,d.performers);    strcpy(label,d.label);    selections = d.selections;    playtime = d.playtime;    return *this;}Classic::Classic(char* s1,char* s2,char* s3,int n,double x):Cd(s1,s2,n,x){    strcpy(works,s3);}Classic::Classic():Cd(){    strcpy(works,"NULL");}Classic & Classic::operator=(const Classic & c){    if(this == &c)        return *this;    Cd::operator=(c);    strcpy(works,c.works);    return *this;}
//main.cpp#include <iostream>#include "cd.h"using namespace std;void Bravo(const Cd & disk);int main(){    Cd c1("Beatles","Capitol",14,25.5);    Classic c2 = Classic("Piano Sonata in B flat,Fantasia in C",        "Alfred Brendel","Philips",2,57.17);    Cd* pcd = &c1;    cout<<"Using object directly:\n";    c1.Report();    c2.Report();    cout<<"Using type cd * pointer to objects:\n";    pcd->Report();//    pcd = &c2;    pcd->Report();//根据指针指向的类型输出    cout<<"Calling a function with a Cd reference argument:\n";    Bravo(c1);    Bravo(c2);    cout<<"Testing assignment: ";    Classic copy;    copy = c2;    copy.Report();    return 0;}void Bravo(const Cd & disk){    disk.Report();//虚函数将根据引用参数指向的实际类型输出}

//13.2

//cd.h --- base class#ifndef CD__H__#define CD__H__class Cd{private:    char* performers;//演员    char* label;//标签    int selections;    double playtime;public:    Cd(char* s1,char* s2,int n,double x);    Cd(const Cd & d);    Cd();    virtual ~Cd();    virtual void Report() const;    virtual Cd & operator=(const Cd & d);};class Classic : public Cd{private:    char* works;public:    Classic(char* s1,char* s2,char* s3,int n,double x);    Classic(const Classic & c);    Classic(char* s3,const Cd & d);    Classic();    virtual ~Classic();    virtual Classic & operator=(const Classic & c);    virtual void Report() const;};#endif
//classic.cpp#include <iostream>#include "cd.h"Cd::Cd(char* s1,char* s2,int n,double x){     performers = new char[strlen(s1)+1];     strcpy(performers,s1);     label = new char[strlen(s2)+1];     strcpy(label,s2);     selections = n;     playtime = x;}Cd::Cd(const Cd & d){    performers = new char[strlen(d.performers)+1];    strcpy(performers,d.performers);    label = new char[strlen(d.label)+1];    strcpy(label,d.label);    selections = d.selections;    playtime = d.playtime;}Cd::Cd(){    performers = new char[strlen("NULL")+1];    strcpy(performers,"NULL");    label = new char[strlen("NULL")+1];    strcpy(label,"NULL");    selections = 0;    playtime = 0.0;}Cd::~Cd(){    delete [] performers;    delete [] label;}void Cd::Report() const{    std::cout<<"The performers is "<<performers<<" ,and the label is "        <<label<<" ,the selections is "<<selections        <<" ,the playtime is "<<playtime<<std::endl;}Cd & Cd::operator=(const Cd & d){    if(this == &d)        return *this;    delete [] performers;    delete [] label;    performers = new char[strlen(d.performers)+1];    strcpy(performers,d.performers);    label = new char[strlen(d.label)+1];    strcpy(label,d.label);    selections = d.selections;    playtime = d.playtime;    return *this;}Classic::Classic(char* s1,char* s2,char* s3,int n,double x):Cd(s1,s2,n,x){    works = new char[strlen(s3)+1];    strcpy(works,s3);}Classic::Classic():Cd(){    works = new char[strlen("NULL")+1];    strcpy(works,"NULL");}Classic::Classic(const Classic & c):Cd(c){    works = new char[strlen(c.works)+1];    strcpy(works,c.works);}Classic::Classic(char* s3,const Cd & d):Cd(d){    works = new char[strlen(s3)+1];    strcpy(works,s3);}Classic::~Classic(){    delete [] works;}Classic & Classic::operator=(const Classic & c){    if(this == &c)        return *this;    Cd::operator=(c);    delete [] works;    works = new char[strlen(c.works)+1];    strcpy(works,c.works);    return *this;}void Classic::Report() const{    Cd::Report();    std::cout<<"The works is "<<works<<std::endl;}
//main.cpp#include <iostream>#include "cd.h"using namespace std;void Bravo(const Cd & disk);int main(){    Cd c1("Beatles","Capitol",14,25.5);    Classic c2 = Classic("Piano Sonata in B flat,Fantasia in C",        "Alfred Brendel","Philips",2,57.17);    Cd* pcd = &c1;    cout<<"Using object directly:\n";    c1.Report();    c2.Report();    cout<<"Using type cd * pointer to objects:\n";    pcd->Report();//    pcd = &c2;    pcd->Report();//根据指针指向的类型输出    cout<<"Calling a function with a Cd reference argument:\n";    Bravo(c1);    Bravo(c2);    cout<<"Testing assignment: ";    Classic copy;    copy = c2;    copy.Report();    // personal test    Cd te_cd1 = Cd("mmdnxh","crazy",1,10.0);    Cd te_cd2 = te_cd1;    te_cd2.Report();    Cd te_cd3 = Cd(te_cd2);    te_cd3.Report();    Cd te_cd4;    te_cd4.Report();    Classic te_cl1;    te_cl1.Report();    Classic te_cl2("Jerry",te_cd1);    te_cl2.Report();    Classic te_cl3 = Classic(te_cl2);    te_cl3.Report();    return 0;}void Bravo(const Cd & disk){    disk.Report();//虚函数将根据引用参数指向的实际类型输出}

//13.3

//dma.h#ifndef DMA__H__#define DMA__H__#include <iostream>class Dma{private:    int rating;public:    Dma(int r = 0);    virtual ~Dma();    virtual void View() const = 0;//ABC};class baseDma : public Dma{private:    char* label;public:    baseDma(const char* l,int r);    baseDma();    baseDma(const baseDma & ba);    ~baseDma();    baseDma & operator=(const baseDma & ba);    void View() const;};class lackDma : public Dma{private:    char* color;public:    lackDma();    lackDma(char* c,int r);    lackDma(const lackDma & la);    ~lackDma();    lackDma & operator=(const lackDma & la);    void View() const;};class hasDma : public Dma{private:    char* style;public:    hasDma();    hasDma(char* c,int r);    hasDma(const hasDma & la);    ~hasDma();    hasDma & operator=(const hasDma & la);    void View() const;};#endif
#include <iostream>#include "dma.h"using std::cin;using std::cout;using std::endl;Dma::Dma(int r){    rating = r;}Dma::~Dma(){}void Dma::View() const{    cout<<"The MDA rating is "<<rating<<endl;}baseDma::baseDma(const char* l,int r):Dma(r){    label = new char[strlen(l)+1];    strcpy(label,l);}baseDma::baseDma():Dma(){    label = new char[strlen("NULL")+1];    strcpy(label,"NULL");}baseDma::baseDma(const baseDma & ba):Dma(ba){    label = new char[strlen(ba.label)+1];    strcpy(label,ba.label);}baseDma::~baseDma(){    delete [] label;}   baseDma & baseDma::operator=(const baseDma & ba){    if(this == &ba)        return *this;    delete [] label;    Dma::operator=(ba);//不需要定义基类的显式的复制构造函数    label = new char[strlen(ba.label)+1];    strcpy(label,ba.label);    return *this;}    //void View() const;void baseDma::View() const//要重定义继承自基类的方法必须要再次声明覆盖它{    Dma::View();    cout<<"The DMA label is "<<label<<endl;}lackDma::lackDma():Dma(){    color = new char[strlen("NULL")+1];    strcpy(color,"NULL");}lackDma::lackDma(char* c,int r):Dma(r){    color = new char[strlen(c)+1];    strcpy(color,c);}lackDma::lackDma(const lackDma & la):Dma(la){    color = new char[strlen(la.color)+1];    strcpy(color,la.color);}lackDma::~lackDma(){delete [] color;}lackDma & lackDma::operator=(const lackDma & la){    if(this == &la)        return *this;    delete [] color;    Dma::operator=(la);//不需要定义基类的显式的复制构造函数    color = new char[strlen(la.color)+1];    strcpy(color,la.color);    return *this;}void lackDma::View() const{    Dma::View();    cout<<"The DMA color is "<<color<<endl;}hasDma::hasDma():Dma(){    style = new char[strlen("NULL")+1];    strcpy(style,"NULL");}hasDma::hasDma(char* c,int r):Dma(r){    style = new char[strlen(c)+1];    strcpy(style,c);}hasDma::hasDma(const hasDma & la):Dma(la){    style = new char[strlen(la.style)+1];    strcpy(style,la.style);}hasDma::~hasDma(){    delete [] style;}hasDma & hasDma::operator=(const hasDma & ha){    if(this == &ha)        return *this;    delete [] style;    Dma::operator=(ha);//不需要定义基类的显式的复制构造函数    style = new char[strlen(ha.style)+1];    strcpy(style,ha.style);    return *this;}void hasDma::View() const{    Dma::View();    cout<<"The DMA style is "<<style<<endl;}
//usebrass3.cpp#include <iostream>#include <string>#include "dma.h"const int CLIENTS = 4;int main(){    using std::cout;    using std::cin;    using std::endl;    Dma * p_clients[CLIENTS];    std::string temp;    long tempnum;    char str[20];    char kind;    for(int i=0;i< CLIENTS;i++)    {        cout<<"Enter a string type data:";        getline(cin,temp);        strcpy(str,temp.c_str());        cout<<"ENter the rating:";        cin>>tempnum;        cout<<"Enter 1 for baseMda Account ,"            <<" 2 for lackMda Account or 3 for hasDma Account: ";        while(cin>>kind && (kind !='1'&&kind != '2'&&kind != '3'))            cout<<"Enter either 1 or 2 or 3:";        if(kind == '1')            p_clients[i] = new baseDma(str,tempnum);        else if(kind == '2')        {            p_clients[i] = new lackDma(str,tempnum);        }        else        {            p_clients[i] = new hasDma(str,tempnum);        }        while(cin.get()!='\n')            continue;    }    cout<<endl;    for(int i=0;i< CLIENTS;i++)    {        p_clients[i]->View();        cout<<endl;    }    for(int i =0;i< CLIENTS;i++)    {    delete p_clients[i];    }    cout<<"Done!\n";    return 0;}

//13.4

#ifndef PORT__H__#define PORT__H__#include <iostream>using namespace std;class Port{private:    char * brand;    char style[20];    int bottles;public:    Port(const char* br = "none",const char * st = "none",int b =0);    Port(const Port & p);    virtual ~Port() {delete [] brand;}    Port & operator=(const Port & p);    Port & operator+=(int b);    Port & operator-=(int b);    int BottleCount() const {return bottles;}    virtual void Show() const;    friend ostream & operator<<(ostream & os,const Port & p);};class VintagePort : public Port{private:    char* nickname;    int year;public:    VintagePort();    VintagePort(const char* br,int b,const char* nn,int y);    VintagePort(const VintagePort & vp);    ~VintagePort(){delete [] nickname;}    VintagePort & operator=(const VintagePort & vp);    void Show() const;    friend ostream & operator<<(ostream & os,const VintagePort & vp);};#endif
#include <iostream>#include "port.h"Port::Port(const char* br ,const char * st ,int b){    brand = new char[strlen(br)+1];    strcpy(brand,br);    int length = strlen(st)>19?19:strlen(st);    strncpy(style,st,length);    if(19 == length)        style[19] = '\0';    else        style[length] = '\0';    bottles = b;}Port::Port(const Port & p){    brand = new char[strlen(p.brand)+1];    strcpy(brand,p.brand);    strcpy(style,p.style);    bottles = p.bottles;}Port & Port::operator=(const Port & p){    if(this == &p)        return  *this;    delete [] brand;    brand = new char[strlen(p.brand)+1];    strcpy(brand,p.brand);    strcpy(style,p.style);    bottles = p.bottles;    return *this;}Port & Port::operator+=(int b){    bottles += b;    return *this;}Port & Port::operator-=(int b){    int temp = bottles - b;    if(temp<0)        cout<<"The number of inputs is too big,operation concealed!\n";    else        bottles -= b;    return *this;}void Port::Show() const{    cout<<"Brand: "<<brand<<endl        <<"Kind: "<<style<<endl        <<"Bottles: "<<bottles<<endl;}ostream & operator<<(ostream & os,const Port & p){    os<<p.brand<<", "<<p.style<<", "<<p.bottles;    return os;}VintagePort::VintagePort():Port(){    nickname = new char[strlen("NULL")+1];    strcpy(nickname,"NULL");    year = 0;}VintagePort::VintagePort(const char* br,int b,const char* nn,int y):Port(br,"none",b){    nickname = new char[strlen(nn)+1];    strcpy(nickname,nn);    year = y;}VintagePort::VintagePort(const VintagePort & vp):Port(vp){    nickname = new char[strlen(vp.nickname)+1];    strcpy(nickname,vp.nickname);    year = vp.year;}VintagePort & VintagePort::operator=(const VintagePort & vp){    if(this == &vp)        return  *this;    Port::operator=(vp);    delete [] nickname;    nickname = new char[strlen(vp.nickname)+1];    strcpy(nickname,vp.nickname);    year = vp.year;    return *this;}void VintagePort::Show() const{    Port::Show();    cout<<"Nickname: "<<nickname<<endl        <<"Year: "<<year<<endl;}ostream & operator<<(ostream & os,const VintagePort & vp){    os<<(const Port &)vp;    os<<", "<<vp.nickname<<", "<<vp.year;    return os;}
//main.cpp#include <iostream>#include "port.h"int main()  {      Port port1= Port("jerry", "mmd", 1);      Port* ptr = &port1;      Port port2 = Port(port1);    ptr->Show();     cout<<endl;    port2.Show();    cout<<endl;    cout<<port1<<endl;    cout<<endl;    VintagePort v1=  VintagePort();      ptr = &v1;      ptr->Show();      cout<<endl;    VintagePort v2 = VintagePort("xxx",1,"yyy",3);    v1 = v2;    cout<<v2 <<endl;     cout<<endl;    return 0;  }  
  • 从函数中可以看到重新定义了Show()方法,因为基类方法不能满足派生类的功能实现,需要重定义。而对于BottleCount()方法,对于两者而言是等价的,不需要重定义。
  • 声明为虚函数的表明派生类要重新定义其继承自基类方法(基类析构函数通常也声明为虚函数,确保析构函数的正确调用),目的在于实现多态。赋值运算符函数是不能继承的,派生类继承的方法的特征标与基类完全相同,但赋值运算符的特征标根据类不同而有所区别。因为它要求的是一个类型为所属类的形参。因此不必声明为虚函数,基类与派生类的赋值运算符函数是独立的,当需要时可以使用作用域解析运算符显式调用。而operator<<()方法是友元函数,亦不能继承。不需要声明为虚函数,需要时将进行强制类型转换。