13.1
//classic.h
class Cd
{
private:
char performers[50];
char label[20];
int selections;
double playtime;
public:
Cd(const char *s1,const char *s2, int n, double x);
//Cd(const Cd&d);//基类没有使用new动态内存分配,可以使用系统默认的复制构造函数
Cd();
virtual ~Cd() {};
virtual void Report()const;
//Cd & operator=(const Cd&d);//基类没有使用new动态内存分配,可以使用系统默认的赋值构造函数
};
class Classic :public Cd
{
private:
char name[50];
public:
Classic(const char *s1,const char *s2,const char *s3, int n, double x);
Classic();
~Classic() {};
void Report()const;
//Classic &operator=(const Classic&);//派生类没有使用new动态内存分配,可以使用系统默认的复制和赋值构造函数
};
//classic.cpp
#include<iostream>
#include<cstring>
#include"classic.h"
//Cd method
Cd::Cd(const char *s1,const char *s2, int n, double x)
{
strcpy(performers, s1);
strcpy(label, s2);
selections = n;
playtime = x;
}
Cd::Cd()
{
performers[0] = label[0] = '\0';
selections = 0;
playtime = 0.0;
}
void Cd::Report()const
{
std::cout << "performers: " << performers
<< "\nlabel: " << label
<< "\nselections: " << selections
<< "\nplatime: " << playtime << std::endl;
}
//classic method
Classic::Classic(const char *s1,const char *s2,const char *s3, int n, double x): Cd(s2,s3,n,x)
{
strcpy(name, s1);
}
Classic::Classic():Cd()
{
name[0] = '\0';
}
void Classic::Report()const
{
std::cout << "name: " << name << std::endl;
Cd::Report();
}
//main.cpp
#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();
}
13.2
//classic.h
class Cd
{
private:
char *performers;
char *label;
int selections;
double playtime;
public:
Cd( const char *s1,const char *s2, int n, double x);
Cd(const Cd&d);
Cd();
virtual ~Cd();
virtual void Report()const;
Cd & operator=(const Cd&d);
};
class Classic :public Cd
{
private:
char *name;
public:
Classic( const char *s1,const char *s2,const char *s3, int n, double x);
Classic();
Classic(const Classic &c);
~Classic() ;
void Report()const;
Classic &operator=(const Classic&c);
};
//classic.cpp
#include<iostream>
#include<cstring>
#include"classic.h"
//Cd method
Cd::Cd( const char *s1,const char *s2, int n, double x)
{
performers = new char[strlen(s1) + 1];
label = new char[strlen(s2) + 1];
strcpy(performers, s1);
strcpy(label, s2);
selections = n;
playtime = x;
}
Cd::Cd()
{
performers = new char[1];
label = new char[1];
performers[0] = label[0] = '\0';
selections = 0;
playtime = 0.0;
}
Cd::~Cd()
{
delete[]label;
delete[]performers;
}
Cd::Cd(const Cd&d)
{
performers = new char[strlen(d.performers) + 1];
label = new char[strlen(d.label) + 1];
strcpy(performers,d.performers);
strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
}
Cd &Cd::operator=(const Cd&d)
{
if (this == &d)
return *this;
delete[]performers;
delete[]label;
performers = new char[strlen(d.performers) + 1];
label = new char[strlen(d.label) + 1];
strcpy(performers, d.performers);
strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
return *this;
}
void Cd::Report()const
{
std::cout << "performers: " << performers
<< "\nlabel: " << label
<< "\nselections: " << selections
<< "\nplatime: " << playtime << std::endl;
std::cout << std::endl;
}
//classic method
Classic::Classic(const char *s1,const char *s2,const char *s3, int n, double x): Cd(s2,s3,n,x)
{
name = new char[strlen(s1) + 1];
strcpy(name, s1);
}
Classic::Classic():Cd()
{
name = new char[1];
name[0] = '\0';
}
Classic::~Classic()
{
delete[]name;
}
Classic::Classic(const Classic &c) :Cd::Cd(c)
{
name = new char[strlen(c.name) + 1];
strcpy(name, c.name);
}
Classic & Classic::operator=(const Classic&c)
{
if (this == &c)
return*this;
Cd::operator=(c);
name = new char[strlen(c.name) + 1];
strcpy(name, c.name);
return *this;
}
void Classic::Report()const
{
std::cout << "name: " << name << std::endl;
Cd::Report();
}
//main.cpp
#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();
}
13.3
//DMA.h
class dmaABC
{
public:
dmaABC(const char*l,int r);
dmaABC(const dmaABC&d);
virtual~dmaABC();
dmaABC & operator=(const dmaABC&d);
virtual void View()const = 0;
private:
char *label;
int rating;
};
class baseDMA:public dmaABC
{
public:
baseDMA(const char *l="null", int r=0) :dmaABC(l, r) {};//即使子类与抽象类相同也必须提供自己的构造函数(包括默认的)
~baseDMA() {};
void View()const;
};
class lacksDMA:public dmaABC
{
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 dmaABC&d);
~lacksDMA() {};//子类没有动态内存分配可以不显示定义析构函数及赋值、复制构造函数
void View()const;
};
class hasDMA :public dmaABC
{
private:
char*style;
public:
hasDMA(const char*s="none", const char* l="null", int r=0);
hasDMA(const char*s, const dmaABC &d);
hasDMA(const hasDMA&h);
~hasDMA();
hasDMA&operator=(hasDMA&h);
void View()const;
};
//DMA.cpp
#include<iostream>
#include<cstring>
#include"DMA.h"
using std::cout;
using std::endl;
dmaABC::dmaABC(const char*l , int r )
{
label = new char[strlen(l) + 1];
strcpy(label, l);
rating = r;
}
dmaABC::dmaABC(const dmaABC&d)
{
label = new char[strlen(d.label) + 1];
strcpy(label, d.label);
rating = d.rating;
}
dmaABC::~dmaABC()
{
delete[]label;
}
void dmaABC::View()const
{
cout << "lable: " << label << endl
<< "rating: " << rating << endl;
cout << endl;
}
dmaABC &dmaABC:: operator=(const dmaABC&d)
{
if (this == &d)
return *this;
delete[] label;
label = new char[strlen(d.label) + 1];
strcpy(label, d.label);
rating = d.rating;
return *this;
}
//baswDMA method
void baseDMA::View()const
{
dmaABC::View();
}
//lacksdma method
lacksDMA::lacksDMA(const char*c, const char*l, int r):dmaABC(l,r)
{
strcpy(color, c);
}
lacksDMA::lacksDMA(const char*c, const dmaABC&d):dmaABC(d)
{
strcpy(color, c);
}
void::lacksDMA::View()const
{
cout << "color: " << color << endl;
dmaABC::View();
}
//haslacksdma method
hasDMA::hasDMA(const char*s, const char* l, int r):dmaABC(l,r)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA::hasDMA(const char*s, const dmaABC &d) : dmaABC(d)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA::hasDMA(const hasDMA&h) : dmaABC(h)
{
style = new char[strlen(h.style) + 1];
strcpy(style, h.style);
}
hasDMA::~hasDMA()
{
delete[]style;
}
hasDMA& hasDMA::operator=(hasDMA&h)
{
if (this == &h)
return *this;
dmaABC::operator=(h);
delete[]style;
style = new char[strlen(h.style) + 1];
strcpy(style, h.style);
return *this;
}
void hasDMA:: View()const
{
cout << "style: " << style << endl;
dmaABC::View();
}
//main.cpp
#include<iostream>
#include<string>
using namespace std;
#include "DMA.h"
const int LENS = 3;
int main()
{
dmaABC *p[LENS];
char l1[40];
int r;
char kind;
for (int i = 0; i < LENS; i++)
{
cout << "enter label: ";
cin.getline(l1, 20);
cout << "enter rating: ";
cin >> r;
cout << "enter 1 for baseDMA, "
<< "2 for lacksDMA "
<< "or 3 for hasDMA: ";
while (cin >> kind && (kind != '1' && kind !=' 2 '&& kind != '3'))//若将 kind换为int型若输入错误将不能再重新输入
{
cout << "enter 1,2 or 3:";
}
//采用int型kind
/*while (!(cin >> kind) && (kind != 1 && kind !=2 && kind != 3))
{
cout << "enter 1,2 or 3:";
cin.clear();
while (cin.get()!='\n')
{
continue;
}
}*/
cin.get();//吸收输入kind后的换行符
if (kind == '1')
{
//cin.get();
p[i] = new baseDMA(l1, r);//new 与&的区别
}
else if (kind =='2')
{
char l2[40];
cout << "enter color: ";
//cin.get();
cin.getline(l2, 40);
p[i] = new lacksDMA(l2, l1, r);
}
else
{
char l2[40];
cout << "enter style: ";
//cin.get();
cin.getline(l2, 40);
p[i] = new hasDMA(l2, l1, r);
}
cout << endl;
}
for (int i = 0; i < LENS; i++)
{
p[i]->View();
}
for (int i = 0; i < LENS; i++)
{
delete p[i];
}
return 0;
}
13.4
//port.h
#include<iostream>
using namespace std;
class Port
{
public:
Port(const char *br="none",const char *st="none",int b=0);
Port(const Port &p);
virtual~Port();
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);
private:
char*brand;
char style[20];
int bottles;
};
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();
VintagePort &operator=(const VintagePort &vp);
void show()const;
friend ostream &operator<<(ostream&os, const VintagePort &vp);
};
//Port.cpp
#include<iostream>
#include<cstring>
using namespace std;
#include"Port.h"
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()
{
delete[]brand;
}
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)
{
bottles -= b;
return *this;
}
void Port::show()const
{
cout << "Brand: " << brand << endl;
cout << "Kind: " << style << endl;
cout << "Bottles: " << bottles << endl;
}
ostream &operator<< (ostream&os, const Port &p)
{
os << p.brand << ", " << p.style << ", " << p.bottles;
return os;
}
//VintagePort method
VintagePort::VintagePort():Port()
{
nickname = new char[1];
nickname[0] = '\0';
year = 0;
}
VintagePort::VintagePort(const char *br, int b, const char *nn, int y):Port(br,"Vintage",b)
{
nickname = new char[strlen(nn) + 1];
strcpy(nickname, nn);
year = y;
}
VintagePort::VintagePort(const VintagePort &vp):Port(vp)
{
delete[]nickname;
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort::~VintagePort()
{
delete[]nickname;
}
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 << endl;
return os;
}
//main.cpp
#include<iostream>
using namespace std;
#include "Port.h"
int main()
{
Port *ptr;
Port p("Gallo", "tawny", 20);
p.show();
ptr = &p;
ptr->show();
std::cout << p;
VintagePort vp("Gallo", 20, "tttt", 20);
vp.show();
std::cout << vp;
ptr = &vp;
ptr->show();
return 0;
}