1. 程式人生 > >C++Primer Plus筆記——第十三章 類繼承課後程式設計練習答案

C++Primer Plus筆記——第十三章 類繼承課後程式設計練習答案

目錄

習題1

習題2

習題3

習題4

課後程式設計練習

習題1

#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();
}

習題2

#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();
}

習題3

///  Test.h
#ifndef _Test_H_
#define _Test_H_
#include <iostream>
using namespace std;
namespace FableGame
{

	class ABC
	{
	private:
		char* label;
		int rating;
	public:
		ABC(const char* l = "null", int r = 0);
		ABC(const ABC& rs);
		virtual ~ABC();
		ABC& operator=(const ABC& rs);
		friend std::ostream& operator<<(std::ostream& os, const ABC& rs);
		virtual void view() = 0;
		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& ls);
		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& hs);
		hasDMA(const hasDMA& hs);
		~hasDMA();
		hasDMA& operator=(const hasDMA& hs);
		friend std::ostream& operator<<(std::ostream& os, const hasDMA& hs);
		virtual void view();
	};
}
#endif




//  Test.cpp
#include "Test.h"
#include <iostream>
#include <cstdlib>
using namespace std;
using namespace FableGame;


FableGame::ABC::ABC(const char* l /*= "null"*/, int r /*= 0*/)
{
	int size = strlen(l) + 1;
	label = new char[size];
	strcpy_s(label, size, l);
	rating = r;
}

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

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

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

void FableGame::ABC::view()
{
	cout << "Label: " << getLabel() << endl;
	cout << "Rating: " << getRating() << endl;
}

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

FableGame::lacksDMA::lacksDMA(const char* c, const char* l, int r) : ABC(l, r)
{
	strncpy_s(color, c, 39);
	color[39] = '\0';
}

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

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

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

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

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

FableGame::hasDMA::hasDMA(const hasDMA& hs) :ABC(hs)
{
	style = new char[strlen(hs.style) + 1];
	strcpy_s(style, strlen(hs.style) + 1, hs.style);
}

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

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

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

std::ostream& FableGame::operator<<(std::ostream& os, const hasDMA& hs)
{
	os << (const ABC&)hs;
	os << "Style: " << hs.style << endl;
	return os;
}

FableGame::baseDMA::baseDMA(const char* l /*= "null"*/, int r /*= 0*/) :ABC(l, r)
{

}

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

}

void FableGame::baseDMA::view()
{
	ABC::view();
}



//main.cpp
#include <iostream>     
#include "Test.h"
#include <string>
using namespace std;
using namespace FableGame;
const int ARR_SIZE = 3;
int main(int argc, const char * argv[])
{
	ABC* p_ABC[ARR_SIZE];
	char temp[40];
	int tempnum;
	int kind;
	for (int i = 0; i < ARR_SIZE; i++)
	{
		cout << "Enter label: ";
		cin.getline(temp, 40);
		cout << "Enter Rating: ";
		cin >> tempnum;

		cout << "Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: ";
		while (cin >> kind && (kind != 1 && kind != 2 && kind != 3))
		{
			cout << "Enter either 1 or 2 or 3: ";
		}
		cin.get();
		if (kind == 1)
		{
			p_ABC[i] = new baseDMA(temp, tempnum);
		}
		else if (kind == 2)
		{
			char color[40];
			cout << "Enter the color: ";
			cin.getline(color, 40);
			p_ABC[i] = new lacksDMA(color, temp, tempnum);
		}
		else if (kind == 3)
		{
			char style[40];
			cout << "Enter the style: ";
			cin.getline(style, 40);
			p_ABC[i] = new hasDMA(style, temp, tempnum);
		}
	}
	cout << endl;
	for (int i = 0; i < ARR_SIZE; i++)
	{
		p_ABC[i]->view();
		cout << endl;
	}
	for (int i = 0; i < ARR_SIZE; i++)
	{
		delete p_ABC[i];
	}
	cout << "Done." << endl;
	return 0;
}

習題4

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