C++ Primer第五版 第十三章编程练习节选(继承、多态、动态内存分配、抽象基类(ABC))
//cd.h
#ifndef CD_H_
#define CD_H_
class Cd
{
private:
char performers[50];
char label[20];
int selections;
double playtime;
public:
Cd();
Cd(const char *pf, const char *lb, int sl, double pt);
Cd(const Cd &cd);
virtual ~Cd();
virtual void report()const;
Cd & operator=(const Cd &cd);
};
class Classic:public Cd
{
private:
char works[40];
public:
Classic();
Classic(const char *wk, const char *pf, const char *lb, int sl, double pt);
Classic(const Classic &cs);
~Classic();
virtual void report()const;
Classic & operator=(const Classic &cs);
};
#endif
//cd.cpp
#include<iostream>
#include<cstring>
#include"cd.h"
using std::cout;
using std::endl;
using std::strcpy;
using std::strlen;
Cd::Cd()
{
strcpy(performers, "none");
strcpy(label, "none");
selections = 0;
playtime = 0.0;
}
Cd::Cd(const char *pf, const char *lb, int sl, double pt)
{
strcpy(performers, pf);
strcpy(label, lb);
selections = sl;
playtime = pt;
}
Cd::Cd(const Cd &cd)
{
strcpy(performers, cd.performers);
strcpy(label, cd.label);
selections = cd.selections;
playtime = cd.playtime;
}
Cd::~Cd()
{
}
void Cd::report()const
{
cout << "Performers : " << performers << endl;
cout << "Label : " << label << endl;
cout << "Selections : " << selections << endl;
cout << "Playtime : " << playtime << endl;
cout << endl;
}
Cd & Cd::operator=(const Cd &cd)
{
if(this == &cd)
{
return *this;
}
strcpy(performers, cd.performers);
strcpy(label, cd.label);
selections = cd.selections;
playtime = cd.playtime;
return *this;
}
Classic::Classic():Cd()
{
strcpy(works, "none");
}
Classic::Classic(const char *wk, const char *pf, const char *lb, int sl, double pt):Cd(pf, lb, sl, pt)
{
strcpy(works, wk);
}
Classic::Classic(const Classic &cs):Cd(cs)
{
strcpy(works, cs.works);
}
Classic::~Classic()
{
}
void Classic::report()const
{
cout << "----- Classic Info -----" << endl;
cout << "Works : " << works << endl;
Cd::report();
}
Classic & Classic::operator=(const Classic &cs)
{
if(this == &cs)
{
return *this;
}
Cd::operator=(cs);
strcpy(works, cs.works);
return *this;
}
//main.cpp
#include<iostream>
#include"cd.h"
using namespace std;
void Bravo(const Cd &cd);
int main()
{
Cd c1("Beatles", "Capitol", 14, 35.5);
Classic c2("Piano Sonata in B flat, Fantasia in C . ", "Alfred Brendel", "Philips", 2, 57.17);
Cd *pcd = &c1;
cout << "Using object directly : \n";
c1.report();
cout << endl;
c2.report();
cout << endl;
cout << "Using type Cd * pointer to object : \n";
pcd->report();
cout << endl;
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();
cout << endl;
return 0;
}
void Bravo(const Cd &cd)
{
cd.report();
cout << endl;
}
//cd.h
#ifndef CD_H_
#define CD_H_
class Cd
{
private:
char *performers;
char *label;
int selections;
double playertime;
public:
Cd();
Cd(const char *pf, const char *lb, int sl, double pt);
Cd(const Cd &cd);
virtual ~Cd();
virtual void report()const;
Cd & operator=(const Cd &cd);
};
class Classic:public Cd
{
private:
char *works;
public:
Classic();
Classic(const char *wk, const char *pf, const char *lb, int sl, double pt);
Classic(const Classic &cs);
~Classic();
virtual void report()const;
Classic & operator=(const Classic &cs);
};
#endif
//cd.cpp
#include<iostream>
#include<cstring>
#include"cd.h"
using std::cout;
using std::endl;
using std::strcpy;
using std::strlen;
Cd::Cd()
{
performers = new char[1];
performers[0] = '\0';
label = new char[1];
label[0] = '\0';
selections = 0;
playertime = 0.0;
}
Cd::Cd(const char *pf, const char *lb, int sl, double pt)
{
performers = new char[strlen(pf) + 1];
strcpy(performers, pf);
label = new char[strlen(lb) + 1];
strcpy(label, lb);
selections = sl;
playertime = pt;
}
Cd::Cd(const Cd &cd)
{
performers = new char[strlen(cd.performers) + 1];
strcpy(performers, cd.performers);
label = new char[strlen(cd.label) + 1];
strcpy(label, cd.label);
selections = cd.selections;
playertime = cd.playertime;
}
Cd::~Cd()
{
delete[] performers;
delete[] label;
}
void Cd::report()const
{
cout << "Performers : " << performers << endl;
cout << "Label : " << label << endl;
cout << "Selections : " << selections << endl;
cout << "Playtime : " << playertime << endl;
cout << endl;
}
Cd & Cd::operator=(const Cd &cd)
{
if(this == &cd)
{
return *this;
}
delete[] performers;
delete[] label;
performers = new char[strlen(cd.performers) + 1];
label = new char[strlen(cd.label) + 1];
strcpy(performers, cd.performers);
strcpy(label, cd.label);
selections = cd.selections;
playertime = cd.playertime;
return *this;
}
Classic::Classic():Cd()
{
works = new char[1];
works[0] = '\0';
}
Classic::Classic(const char *wk, const char *pf, const char *lb, int sl, double pt):Cd(pf, lb, sl, pt)
{
works = new char[strlen(wk) + 1];
strcpy(works, wk);
}
Classic::Classic(const Classic &cs):Cd(cs)
{
works = new char[strlen(cs.works) + 1];
strcpy(works, cs.works);
}
Classic::~Classic()
{
delete[] works;
}
void Classic::report()const
{
cout << "----- Classic Info -----" << endl;
cout << "Works : " << works << endl;
Cd::report();
}
Classic & Classic::operator=(const Classic &cs)
{
if(this == &cs)
{
return *this;
}
Cd::operator=(cs);
delete[] works;
works = new char[strlen(cs.works) + 1];
strcpy(works, cs.works);
return *this;
}
//main.cpp
#include<iostream>
#include"cd.h"
using namespace std;
void Bravo(const Cd &cd);
int main()
{
Cd c1("Beatles", "Capitol", 14, 35.5);
Classic c2("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 object : \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 &cd)
{
cd.report();
cout << endl;
}
//dma.h
#ifndef DMA_H_
#define DMA_H_
#include<iostream>
class baseDMA
{
private:
char *label;
int rate;
public:
baseDMA(const char *lb = "null", int r = 0);
baseDMA(const baseDMA &b);
virtual ~baseDMA();
const char *showLabel()const{return label;};
int showRate()const{return rate;};
baseDMA & operator=(const baseDMA &b);
virtual void show()const;
friend std::ostream & operator<<(std::ostream &os, const baseDMA &b);
};
class lacksDMA:public baseDMA
{
private:
enum{COL_LEN = 40};
char color[COL_LEN];
public:
lacksDMA(const char *co = "black", const char *lb = "null", int r = 0);
lacksDMA(const char *co, const baseDMA &bd);
const char *showColor()const{return color;};
virtual void show()const;
friend std::ostream & operator<<(std::ostream &os, const lacksDMA &ld);
};
class hasDMA:public baseDMA
{
private:
char *style;
public:
hasDMA(const char *st = "none", const char *lb = "null", int r = 0);
hasDMA(const char *st, const baseDMA &bd);
hasDMA(const hasDMA &hd);
~hasDMA();
const char *showStyle()const{return style;};
hasDMA & operator=(const hasDMA &hd);
virtual void show()const;
friend std::ostream & operator<<(std::ostream &os, const hasDMA &hd);
};
#endif
//dma.cpp
#include<cstring>
#include"dma.h"
using std::cout;
using std::endl;
using std::strcpy;
using std::strncpy;
using std::strlen;
using std::ostream;
baseDMA::baseDMA(const char *lb, int r)
{
label = new char[strlen(lb) + 1];
strcpy(label, lb);
rate = r;
}
baseDMA::baseDMA(const baseDMA &bd)
{
label = new char[strlen(bd.label) + 1];
strcpy(label, bd.label);
rate = bd.rate;
}
baseDMA::~baseDMA()
{
delete[] label;
}
baseDMA & baseDMA::operator=(const baseDMA &bd)
{
if(this == &bd)
{
return *this;
}
delete[] label;
label = new char[strlen(bd.label) + 1];
strcpy(label, bd.label);
rate = bd.rate;
return *this;
}
void baseDMA::show()const
{
cout << "Label : " << showLabel() << endl;
cout << "Rate : " << showRate() << endl;
}
ostream & operator<<(ostream &os, const baseDMA &bd)
{
os << "Label : " << bd.label << endl;
os << "Rate : " << bd.rate << endl;
return os;
}
lacksDMA::lacksDMA(const char *co, const char *lb, int r):baseDMA(lb, r)
{
strncpy(color, co, 39);
color[39] = '\0';
}
lacksDMA::lacksDMA(const char *co, const baseDMA &bd):baseDMA(bd)
{
strncpy(color, co, COL_LEN - 1);
color[COL_LEN - 1] = '\0';
}
void lacksDMA::show()const
{
cout << "Label : " << showLabel() << endl;
cout << "Rate : " << showRate() << endl;
cout << "Color : " << showColor() << endl;
}
ostream & operator<<(ostream &os, const lacksDMA &ld)
{
os << (const baseDMA &)ld;
os << "Color : " << ld.color << endl;
return os;
}
hasDMA::hasDMA(const char *st, const char *lb, int r):baseDMA(lb, r)
{
style = new char[strlen(st) + 1];
strcpy(style, st);
}
hasDMA::hasDMA(const char *st, const baseDMA &bd):baseDMA(bd)
{
style = new char[strlen(st) + 1];
strcpy(style, st);
}
hasDMA::hasDMA(const hasDMA &hd):baseDMA(hd)
{
style = new char[strlen(hd.style) + 1];
strcpy(style, hd.style);
}
hasDMA::~hasDMA()
{
delete[] style;
}
hasDMA & hasDMA::operator=(const hasDMA &hd)
{
if(this == &hd)
{
return *this;
}
baseDMA::operator=(hd);
style = new char[strlen(hd.style) + 1];
strcpy(style, hd.style);
return *this;
}
void hasDMA::show()const
{
cout << "Label : " << showLabel() << endl;
cout << "Rate : " << showRate() << endl;
cout << "Style : " << showStyle() << endl;
}
ostream & operator<<(ostream &os, const hasDMA &hd)
{
os << (const baseDMA &)hd;
os << "Style : " << hd.style << endl;
return os;
}
//main.cpp
#include<iostream>
#include"dma.h"
using namespace std;
int main()
{
baseDMA *p_b[5];
for(int i = 0; i < 5; i++)
{
char lb[40];
int r;
char c;
cout << "Enter the label : " ;
cin>>lb;
cout << "Enter the rate : ";
cin >> r;
cout << "Enter 1(bassDMA) , 2(lacksDMA), 3(hasDMA) to save your date :";
cin >> c;
switch(c)
{
case '1':
p_b[i] = new baseDMA(lb, r);
break;
case '2':
char co[40];
cout << "Enter the color :";
cin>>co;
cin.get();
p_b[i] = new lacksDMA(co, lb, r);
break;
case '3':
char st[40];
cout << "Enter the style : ";
cin>>st;
cin.get();
p_b[i] = new hasDMA(st, lb, r);
break;
default:
cout << "Only 1 , 2, 3 is allowed to enter !" << endl;
}
}
cout << "Tthe date you enter are following : " << endl;
for(int i = 0; i < 5; i++)
{
cout << "# " << i + 1 << " : " << endl ;
p_b[i]->show();
cout << endl;
}
for(int i = 0; i < 5; i++)
{
delete p_b[i];
}
cout << "done . " << endl;
return 0;
}
practice makes perfect!