C++ primer plus 第六版 第十三章 编程练习答案

第十三章 编程练习答案

1.

//头文件
#ifndef CD_H_
#define CD_H_

//Brass Cd 类
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;
    Cd & operator=(const Cd & d);
};

//Brass Classic 类
class Classic : public Cd
{
private:
    char name[20];
public:
    Classic(char * s1, char * s2, char * s3, int n, double x);
    Classic(const Classic & d, char * c);
    Classic(const Classic & d);
    Classic();

    virtual void Report() const;    
    Classic & operator=(const Classic & d);
};

#endif
//类的实现
#include <iostream>
#include <cstring>
#include "classic.h"
using std::cout;
using std::endl;
using std::strcpy;

//Cd 实现方法 
Cd::Cd(char * s1, char * s2, int n, double x)
{
    strcpy(performers, s1);
    strcpy(label, s2);
    selections = n;
    playtime = x;   
}

Cd::Cd(const Cd & d)
{
    strcpy(performers, d.performers);
    strcpy(label, d.label);
    selections = d.selections;
    playtime = d.playtime;  
}

Cd::Cd()
{
    performers[0] = '\0';
    label[0] = '\0';
    selections = 0; 
    playtime = 0;
}

Cd::~Cd()
{   
}

void Cd::Report() const
{
    cout << "performers: "<< performers << endl;
    cout << "label: " << label << endl;
    cout << "number of selections: " << selections << endl; 
    cout << "playing time in minutes: " << playtime << endl;
    cout << 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::Classic(char * s1, char * s2, char * s3, int n, double x) : Cd(s1, s2, n, x)
{
    strcpy(name, s3);
}

Classic::Classic(const Classic & d, char * c) : Cd(d) 
{
    strcpy(name, c);    
}

Classic::Classic()
{
}

//重新定义report 
void Classic::Report() const
{
    cout << "name: " << name << endl;
    Cd::Report();       
}


Classic & Classic::operator=(const Classic & d)
{
    if (this == &d)
        return *this;
    Cd::operator=(d);
    strcpy(name, d.name);   
    return *this;
}
//主程序
#include <iostream>
using namespace std;
#include "classic.h"
void Bravo(const Cd & disk);
int main()
{
    Cd c1("Beatles", "Capitol", 14, 35.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();
}

2.

动态内存分配,要记得析构函数时要使用delete指针。

//头文件
#ifndef CD_H_
#define CD_H_

//Brass Cd 类
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;
    Cd & operator=(const Cd & d);
};

//Brass Classic 类
class Classic : public Cd
{
private:
    char * name;
public:
    Classic(char * s1, char * s2, char * s3, int n, double x);
    Classic(const Classic & d, char * c);
    Classic(const Classic & d);
    Classic();
    ~ Classic();

    virtual void Report() const;    
    Classic & operator=(const Classic & d);
};

#endif
//类的实现
#include <iostream>
#include <cstring>
#include "classic10.h"
using std::cout;
using std::endl;
using std::strcpy;
using std::strlen;

//Cd 实现方法 
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[1];
    performers[0] = '\0';
    label = new char[1];
    label[0] = '\0';
    selections = 0; 
    playtime = 0;
}

Cd::~Cd()
{
    delete [] label;
    delete [] performers;   
}

void Cd::Report() const
{
    cout << "performers: "<< performers << endl;
    cout << "label: " << label << endl;
    cout << "number of selections: " << selections << endl; 
    cout << "playing time in minutes: " << playtime << endl;
    cout << endl;   
}

Cd & Cd::operator=(const Cd & d)
{
    if (this == &d)
        return *this;
    delete [] label;
    delete [] performers;
    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::Classic(char * s1, char * s2, char * s3, int n, double x) : Cd(s1, s2, n, x)
{
    name = new char[strlen(s3) + 1];        
    strcpy(name, s3);
}

Classic::Classic(const Classic & d, char * c) : Cd(d) 
{
    name = new char[strlen(d.name) + 1];    
    strcpy(name, c);    
}

Classic::Classic()
{
    name = new char[1];
    name[0] = '\0';
}

Classic::~Classic()
{
    delete [] name; 
}

//重新定义report 
void Classic::Report() const
{
    cout << "name: " << name << endl;
    Cd::Report();       
}


Classic & Classic::operator=(const Classic & d)
{
    if (this == &d)
        return *this;
    Cd::operator=(d);       
    delete [] name;
    name = new char[strlen(d.name) + 1];
    strcpy(name, d.name);   
    return *this;
}
//主程序,题一稍作修改
#include <iostream>
using namespace std;
#include "classic10.h"
void Bravo(const Cd & disk);
int main()
{
    Cd c1("Beatles", "Capitol", 14, 35.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: \n";
    Classic copy;
    copy= c2;
    copy.Report();
    return 0;
}

void Bravo(const Cd & disk)
{
    disk.Report();
}

3.

//头文件
#ifndef ABC_H_
#define ABC_H_

#include <iostream>

//抽象基类
class ABC
{
private:
    char * label;
//char *需要深度复制,string类不需要 
    int rating; 
public:
    ABC(const char * l = "null", int r = 0);
    ABC(const ABC & rs);
    ABC & operator=(const ABC & rs);

    virtual ~ABC();    
    virtual void View() = 0;
    friend std::ostream& operator<<(std::ostream& os, const ABC& rs);
    char * getLabel(){ return label; }
    int getRating(){ return rating; }   
};

class baseDMA : public ABC
{
public:
    baseDMA(const char * l = "null", int r = 0);
    baseDMA(const baseDMA & rs);

    virtual void View();
};

class lacksDMA : public ABC
{
private:
    enum { COL_LEN =40};
    char color[COL_LEN];
public:
    lacksDMA(const char * c = "blank", const char * l = "null", int r = 0);
    lacksDMA(const char * c, const ABC & rs);

    friend std::ostream& operator<<(std::ostream& os, const lacksDMA& ls);
    virtual void View();
};

class hasDMA : public ABC
{
private:
    char * style;
public:
    hasDMA(const char * s = "none", const char * l = "null", int r = 0);
    hasDMA(const char * s, const ABC & rs); 
    hasDMA(const hasDMA & hs);
    ~hasDMA();

    hasDMA & operator=(const hasDMA & hs);
    friend std::ostream& operator<<(std::ostream& os, const hasDMA& hs);    
    virtual void View();        
};

#endif
//类的实现
#include <iostream>
#include <cstring>
#include "U13p3abc.h"

using std::cout;
using std::endl;
using std::strcpy;

//抽象基类
ABC::ABC(const char * l, int r)
{
    label = new char[strlen(l) + 1];
    strcpy(label, l);
    rating = r;
}

ABC::ABC(const ABC & rs)
{
    label = new char[strlen(rs.label) + 1];
    strcpy(label, rs.label);
    rating = rs.rating;
}

ABC & ABC::operator=(const ABC & rs)
{
    if (this == &rs)
        return *this;
    delete [] label;
    label = new char[strlen(rs.label) + 1];
    strcpy(label, rs.label);
    rating = rs.rating;
    return *this;
}

ABC::~ABC()
{   
    delete [] label;
}

void ABC::View()
{
    cout << "Label: " << label << endl;
    cout << "Rating: " << rating << endl;   
}

std::ostream& operator<<(std::ostream& os, const ABC& rs)
{
    os << "Label: " << rs.label << endl;
    os << "Rating: " << rs.rating << endl;
    return os;  
}

//基类
baseDMA::baseDMA(const char * l, int r) : ABC(l, r)
{
}

baseDMA::baseDMA(const baseDMA & rs) : ABC(rs) 
{
}

void baseDMA::View()
{
    ABC::View();
}

//lacksbase类
lacksDMA::lacksDMA(const char * c, const char * l, int r) : ABC(l, r)
{   
    std::strcpy(color, c);  
    color[COL_LEN - 1] = '\0';
}

lacksDMA::lacksDMA(const char * c, const ABC & rs) : ABC(rs)
{
    std::strcpy(color, c);
    color[COL_LEN - 1] = '\0';

}

std::ostream& operator<<(std::ostream& os, const lacksDMA & ls)
{
    os << (const ABC&)ls;
    os << "Color: " << ls.color << endl;
    return os;  
}

void lacksDMA::View()
{
    ABC::View();            
    cout << "Color: " << color << endl;     
}

//hasbase类  
hasDMA::hasDMA(const char * s, const char * l, int r) :ABC(l, r)
{   
    style = new char[strlen(s) + 1];
    strcpy(style, s);   
}

hasDMA::hasDMA(const char * s, const ABC & rs) : ABC(rs)
{
    style = new char[strlen(s) + 1];
    strcpy(style, s);
}

hasDMA::~hasDMA()
{
    delete [] style;
}

void hasDMA::View()
{
    ABC::View();        
    cout << "Style: " << style << endl; 
}

hasDMA & hasDMA::operator=(const hasDMA & hs)
{
    if (this == &hs)
        return *this;
    delete [] style;
    ABC::operator=(hs);
    style = new char[strlen(hs.style) + 1];
    strcpy(style, hs.style);
    return *this;
}

std::ostream& operator<<(std::ostream& os, const hasDMA& hs)
{
    os << (const ABC&)hs;
    os << "Style: " << hs.style << endl;
    return os;
}
//主程序
#include <iostream>
#include <string>
#include <cstring>
#include "U13p3abc.h"

const int BASE = 3;

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;

    ABC * p_base[BASE];
    char temp[40];
    char tcolor[40];        
    char tstyle[40];            
    int tempnum;
    int kind;

    for (int i = 0; i < BASE; i++)
    {
        cout << "Enter base's label: " << endl;
        cin.getline(temp, 40);
        cout << "Enter base's rating: " << endl;
        cin >> tempnum;
        cout << "Enter 1 for base, 2 for lacksbase or 3 for hasbase: " << endl;
        while (cin >> kind && (kind != 1 && kind != 2 && kind != 3))
        {
            cout << "Enter either 1, 2 or 3: " << endl;
        }
        //混合输入数字和字符时记得注意,
        //数字输入后留换行符在输入队列中,并没去掉、 
        cin.get();//去掉换行符 
        if (kind == 1)
        {
            p_base[i] = new baseDMA(temp, tempnum);         
        }
        else if (kind == 2)
        {

            cout << "Enter the color: " << endl;        
            cin.get(tcolor, 40);        
            p_base[i] = new lacksDMA(tcolor, temp, tempnum);    
        }
        else if (kind == 3)
        {
            cout << "Enter the style: " << endl;
            cin.getline(tstyle, 40);        
            p_base[i] = new hasDMA(tstyle, temp, tempnum);
        }   
        while (cin.get() != '\n')
            continue;   
    }           
    cout << endl;
    for (int i = 0; i < BASE; i++)
    {
        p_base[i]->View();
        cout << endl;
    }

    for (int i = 0; i < BASE; i++)
    {
        delete p_base[i];//释放对象 
    }
    cout << "Done.\n";
    return 0;
}

4.

b)内联函数不需要再重新定义了。
c)operator=()不能继承,因为赋值运算符不能将父类赋值给子类。operator<<()是友元函数,不能声明为虚函数。

//头文件
#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, const char * st, 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 <cstring>
#include "U13p4port.h"

//port类
Port::Port(const char * br, const char * st, int b)
{
    brand = new char[strlen(br) + 1];
    strcpy(brand, br);  
    strcpy(style, st);  
    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 (&p == this)
        return (*this);
    delete [] brand;
    brand = new char[strlen(p.brand) + 1];
    strcpy(brand, p.brand); 
    strcpy(style, p.style);
    bottles = p.bottles;    
}

Port & Port::operator+=(int b)
{
    bottles += b;
    return *this;//记得返回值    
}


Port & Port::operator-=(int b)
{
    if(bottles >= b)
        bottles -= b;   
    if(bottles < b)
        std::cout << "You don't have enough bottles.";
    return *this;//记得返回值
}

void Port::Show() const
{
    std::cout << "Brand: " << brand << std::endl;
    std::cout << "Kind: " << style << std::endl;
    std::cout << "Bottles: " << bottles << std::endl;   
}

ostream & operator<<(ostream & os, const Port & p)
{
    os << p.brand << ", " << p.style << ", " << p.bottles;
    return os;
}

//vintageport类
VintagePort::VintagePort() : Port() 
{
    nickname = new char[1];
    nickname[0] = '\0';
    year = 0;
}

VintagePort::VintagePort(const char * br, const char * st, int b, const char * nn, int y) : Port(br, st, 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 (&vp == this)
        return (*this);
    Port::operator=(vp);
    delete [] nickname;     
    nickname = new char[strlen(vp.nickname) + 1];
    strcpy(nickname, vp.nickname);      
    year = vp.year;     
} 

void VintagePort::Show() const
{
    Port::Show();
    std::cout << "Nickname: " << nickname << std::endl;
    std::cout << "Year: " << year << std::endl; 
}

ostream & operator<<(ostream & os, const VintagePort & vp)
{
    os << (const Port&)vp;
    os << ", " << vp.nickname << ", " << vp.year;
    return os;  
}
//测试程序
#include <iostream>
#include <string>
#include "U13p4port.h"
using std::cout;
using std::endl;

int main()
{
    Port port1("gallo", "tawny", 20);
    cout << port1 << endl << endl;
    VintagePort vp("gallo", "vintage", 24, "Old Velvet", 16);
    VintagePort vp2(vp);
    cout << vp2 << endl << endl;
    VintagePort vp3;
    vp3 = vp;
    cout << vp3 << endl << endl;

    Port * p_port;
    p_port = &port1;
    p_port->Show();
    cout << endl;
    p_port = &vp;
    p_port->Show();
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41882882/article/details/81908317
今日推荐