首页 > 代码库 > c++ primer plus(第6版)中文版 第十三章编程练习答案

c++ primer plus(第6版)中文版 第十三章编程练习答案

第十三章编程练习答案

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;
}