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

//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<<()方法是友元函数,亦不能继承。不需要声明为虚函数,需要时将进行强制类型转换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值