第十三章编程练习答案
13.1根据Cd基类,完成派生出一个Classic类,并测试
//13.1根据Cd基类,完成派生出一个Classic类,并测试
#include <iostream>
#include <cstring>
using namespace std;
// base class
class Cd
{
char performers[50];
char label[20];
int selections; // number of selections
double playtime; // playing time in minutes
public:
explicit Cd(const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0);
virtual ~Cd() {}
virtual void Report() const; // reports all CD data
};
static void cpStr (char* p_des_txt, const char* p_src_txt, unsigned des_arr_size)
{
unsigned str_len = strlen(p_src_txt) < des_arr_size-1 ? strlen(p_src_txt) : des_arr_size-1;
strncpy(p_des_txt, p_src_txt, str_len);
p_des_txt[str_len] = '\0';
}
Cd::Cd (const char * s1, const char * s2, int n, double x)
: selections(n), playtime(x)
{
cpStr(performers, s1, 50);
cpStr(label, s2, 20);
}
void Cd::Report() const
{
cout << performers << ", " << label << ", " << selections << ", " << playtime << flush;
}
class Classic : public Cd
{
static const unsigned mk_size = 64;
char m_songs[mk_size];
public:
Classic (const char* songs_list = "", const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0);
virtual void Report() const; // reports all CD data
};
Classic::Classic (const char* songs_list, const char * s1, const char * s2, int n, double x)
: Cd(s1, s2, n, x)
{
cpStr(m_songs, songs_list, mk_size);
}
void Classic::Report () const
{
Cd::Report();
cout << ", " << m_songs << endl;
}
void Bravo(const Cd & disk)
{
disk.Report();
cout << endl;
}
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(); // use Cd method
c2.Report(); // use Classic method
cout << "Using type cd * pointer to objects:\n";
pcd->Report(); // use Cd method for cd object
pcd = &c2;
pcd->Report(); // use Classic method for classic object
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
Bravo(c2);
cout << "Testing assignment: ";
Classic copy;
copy = c2;
copy.Report();
}
13.2对13.1,使用动态内存记录字符串
//13.2对13.1,使用动态内存记录字符串
#include <iostream>
#include <cstring>
using namespace std;
// base class
class Cd
{
char* performers;
char* label;
int selections; // number of selections
double playtime; // playing time in minutes
public:
explicit Cd(const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0);
Cd(const Cd & d);
virtual ~Cd();
virtual void Report() const; // reports all CD data
Cd & operator=(const Cd & d);
};
static char* cpNewStr (const char* p_src_txt)
{
unsigned str_len = strlen(p_src_txt);
char* p_des_txt = new char [str_len + 1];
strcpy(p_des_txt, p_src_txt);
return (p_des_txt);
}
Cd::Cd (const char * s1, const char * s2, int n, double x)
: selections(n), playtime(x)
{
performers = cpNewStr(s1);
label = cpNewStr(s2);
}
Cd::~Cd ()
{
delete [] performers;
delete [] label;
}
Cd::Cd(const Cd & d)
: selections(d.selections), playtime(d.playtime)
{
performers = cpNewStr(d.performers);
label = cpNewStr(d.label);
}
Cd & Cd::operator=(const Cd & d)
{
if (&d == this) {
return (*this);
}
delete [] performers;
performers = cpNewStr(d.performers);
delete [] label;
label = cpNewStr(d.label);
selections = d.selections;
playtime = d.playtime;
return (*this);
}
void Cd::Report() const
{
cout << performers << ", " << label << ", " << selections << ", " << playtime << flush;
}
// derive
class Classic : public Cd
{
char* songs;
public:
explicit Classic (const char* songs_list = "", const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0);
Classic (const Classic& classic);
virtual ~Classic ();
Classic& operator= (const Classic& classic);
virtual void Report() const; // reports all CD data
};
Classic::Classic (const char* songs_list, const char * s1, const char * s2, int n, double x)
: Cd(s1, s2, n, x)
{
songs = cpNewStr(songs_list);
}
Classic::Classic (const Classic& classic)
: Cd(classic)
{
songs = cpNewStr(classic.songs);
}
Classic::~Classic ()
{
delete [] songs;
}
Classic & Classic::operator= (const Classic& classic)
{
if (&classic == this)
return (*this);
Cd::operator=(classic);
delete [] songs;
songs = cpNewStr(classic.songs);
return (*this);
}
void Classic::Report () const
{
Cd::Report();
cout << ", " << songs << endl;
}
void Bravo(const Cd & disk)
{
disk.Report();
cout << endl;
}
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(); // use Cd method
c2.Report(); // use Classic method
cout << "Using type cd * pointer to objects:\n";
pcd->Report(); // use Cd method for cd object
pcd = &c2;
pcd->Report(); // use Classic method for classic object
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
Bravo(c2);
cout << "Testing assignment: ";
Classic copy;
copy = c2;
copy.Report();
}
13.3让三个类从一个基类DMA继承而来,然后用程序清单13.10对比测试,基类使用虚类。
//13.3让三个类从一个基类DMA继承而来,然后用程序清单13.10对比测试,基类使用虚类。
#include <iostream>
#include <string>
using namespace std;
class DMA{
string label;
int rating;
public:
DMA(const string l="null",int r=0)
{
label=l;
rating=r;
}
virtual void test(){};
virtual void tese2() { cout<<"test2"; }
DMA(const DMA &rs)
{
label=rs.label;
rating=rs.rating;
}
virtual ~DMA() {}
string lab() {return label;}
int ra() {return rating;}
friend ostream&operator<<(ostream &os,const DMA &rs)
{
os<<"label:"<<rs.label<<" rating:"<<rs.rating<<endl;
return os;
}
virtual void show()
{
cout<<"label:"<<label<<" rating:"<<rating<<" "<<endl;
}
};
class baseDMA:public DMA
{
public:
baseDMA(const string l="null",int r=0):DMA(l,r)
{}
baseDMA(baseDMA &bd):DMA(bd.lab(),bd.ra())
{}
virtual void test()const{};
virtual ~baseDMA(){}
friend ostream&operator<<(ostream &os,const baseDMA &bd)
{
os<<"This is baseDMA: ";
os<<(DMA &)bd;
return os;
}
virtual void show()
{
cout<<"This is baseDMA: ";
DMA::show();
cout<<endl;
}
};
class lacksDMA:public DMA
{
string color;
public:
lacksDMA(const string c="blank",const string l="null",int r=0):DMA(l,r)
{
color=c;
}
virtual ~lacksDMA(){};
virtual void test()const{};//必须实现虚基类的所有虚函数
friend ostream&operator<<(ostream &os,const lacksDMA &ld)
{
os<<"This is lacksDMA: ";
os<<(DMA &)ld<<" color:"<<ld.color;//通过强制类型转换调用基类友元函数
return os;
}
virtual void show()
{
cout<<"This is lacksDMA: ";
DMA::show();
cout<<" color:"<<color;
cout<<endl;
}
};
class hasDMA:public DMA
{
string style;
public:
hasDMA(const string s="none",const string l="null",int r=0):DMA(l,r)
{
style=s;
}
virtual ~hasDMA(){};
virtual void test()const{};//必须实现虚基类的所有虚函数
virtual void show()
{
cout<<"This is hasDMA: ";
DMA::show();
cout<<" style:"<<style;
cout<<endl;
}
friend ostream&operator<<(ostream &os,const hasDMA &hd)
{
os<<"This is hasDMA: ";
os<<(DMA &)hd<<" style:"<<hd.style;//通过强制类型转换调用基类友元函数
return os;
}
};
int main ()
{
DMA *pd[3];//虚基类不能创建对象,但可以创建指向其的指针
for(int i=0;i<3;i++)
{
cout<<"\nEnter the label:";
string label;
getline(cin,label,'\n');
cout<<"\nEnter the rating:";
int rat;
cin>>rat;
cout<<"Enter the 1 for baseDMA"<<endl
<<"2 for lacksDMA"<<endl
<<"3 for hasDMA"<<endl;
int temp;
cin>>temp;
cin.get();
if(temp==1)
pd[i]=new baseDMA(label,rat);
else if(temp==2)
{
cout<<"Enter the color:";
string color;
getline(cin,color);
pd[i]=new lacksDMA(color,label,rat);
}
else if(temp==3)
{
cout<<"Enter the style:";
string style;
getline(cin,style);
pd[i]=new hasDMA(style,label,rat);
}
else
{
cout<<"invalid input! try again!"<<endl;
i--;
}
while(cin.get()!='\n')
continue;
}
cout<<endl;
for(int i=0;i<3;i++)
pd[i]->show();
}
13.4根据Port类派生出一个VintagePort类,完成并测试
//13.4根据Port类派生出一个VintagePort类,完成并测试
#include <iostream>
#include <cstring>
using namespace std;
class Port
{
char * brand;
char style[20]; // i.e., tawny, ruby, vintage
int bottles;
public:
explicit Port(const char * br = "none", const char * st = "none", int b = 0);
Port(const Port & p); // copy constructor
virtual ~Port() { delete [] brand; }
Port & operator=(const Port & p);
virtual void Show() const;
Port & operator+=(int b); // adds b to bottles
Port & operator-=(int b); // subtracts b from bottles, if available
int BottleCount() const { return bottles; }
friend ostream & operator<<(ostream & os, const Port & p);
};
static char* cpNewStr (const char* p_src_txt)
{
unsigned str_len = strlen(p_src_txt);
char* p_des_txt = new char [str_len + 1];
strcpy(p_des_txt, p_src_txt);
return (p_des_txt);
}
static void cpStr (char* p_des_txt, const char* p_src_txt, unsigned des_arr_size)
{
unsigned str_len = strlen(p_src_txt) < des_arr_size-1 ? strlen(p_src_txt) : des_arr_size-1;
strncpy(p_des_txt, p_src_txt, str_len);
p_des_txt[str_len] = '\0';
}
Port::Port (const char * br, const char * st, int b)
: brand(cpNewStr(br)), bottles(b)
{
cpStr(style, st, 20);
}
Port::Port(const Port & p)
: brand(cpNewStr(p.brand)), bottles(p.bottles)
{
cpStr(style, p.style, 20);
}
void Port::Show() const
{
cout << "Brand: " << brand << endl
<< "Style: " << style << endl
<< "Bottles: " << bottles << flush;
}
Port & Port::operator=(const Port & p)
{
if (&p == this)
return (*this);
delete [] brand;
brand = cpNewStr(p.brand);
cpStr(style, p.style, 20);
bottles = p.bottles;
return (*this);
}
Port & Port::operator+=(int b)
{
bottles += b;
return (*this);
}
Port & Port::operator-=(int b)
{
bottles -= b;
return (*this);
}
ostream & operator<< (ostream & os, const Port & p)
{
cout << p.brand << ", " << p.style << ", " << p.bottles << flush;
return (os);
}
class VintagePort : public Port // style necessarily = "vintage"
{
char * nickname; // i.e., "The Noble" or "Old Velvet", etc.
int year; // vintage year
public:
explicit VintagePort(const char * br = "", int b = 0, const char * nn = "", int y = 0);
VintagePort(const VintagePort & vp);
virtual ~VintagePort() { delete [] nickname; }
VintagePort & operator=(const VintagePort & vp);
virtual void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};
VintagePort::VintagePort (const char * br, int b, const char * nn, int y)
: Port(br, "vintage", b), nickname(cpNewStr(nn)), year(y) {}
VintagePort::VintagePort (const VintagePort & vp)
: Port(vp), nickname(cpNewStr(vp.nickname)), year(vp.year) {}
void VintagePort::Show () const
{
Port::Show();
cout << endl;
cout << "Nickname: " << nickname << endl;
cout << "Year: " << year << flush;
}
VintagePort & VintagePort::operator= (const VintagePort & vp)
{
if (&vp == this)
return (*this);
Port::operator=(vp);
delete [] nickname;
nickname = cpNewStr(vp.nickname);
year = vp.year;
return (*this);
}
ostream & operator<< (ostream & os, const VintagePort & vp)
{
os << Port(vp);
cout << ", " << vp.nickname << ", " << vp.year << flush;
return (os);
}
int main()
{
Port port1("gallo", "tawny", 20);
cout << port1 << endl << endl;
VintagePort vp("gallo", 24, "nice", 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;
}
c++ primer plus(第6版)中文版 第十三章编程练习答案,布布扣,bubuko.com
c++ primer plus(第6版)中文版 第十三章编程练习答案