C++Primer Plus第6版第13章编程练习答案

第一题

 classic.h

#include<iostream>
#ifndef CD_H_
#define CD_H_

class Cd
{
private:
	char performers[50];
	char label[20];
	int selections;	
	double playtime;
public:
	/*
	* 一定要声明这种形式,因为传入实参字符串的时候
	*比如"hello"这种形式为字符串常量不可修改其内容
	*比较先进的编译器不声明为const的时候编译不通过
	*/
	Cd(const char* s1,const char* s2, int n, double x);
	//不需要复制
	Cd() { performers[0] = label[0] = '\0'; selections = playtime = 0.0; }
	virtual ~Cd(){ }
	virtual void Report()const 
	{
		std::cout << "performers: " << performers << "\nlabel: " << label 
				  << "\nselections: " << selections << "\nplaytime: " << playtime;
		std::cout << std::endl;
	}
	//不需要赋值
};

class Classic : public Cd 
{
private:
	char opus[50];
public:
	Classic() : Cd() { opus[0] = '\0'; }
	Classic(const char* opus, const char* performers, const char* label, 
		int selections, double playtime) : Cd(performers,label,selections,playtime)
	{
		strncpy(this->opus, opus,49);
		this->opus[49] = '\0';
	}

	virtual void Report()const
	{
		Cd::Report();
		std::cout << "opus: " << opus;
		std::cout << std::endl;
	}
	virtual ~Classic() { }	//该析构函数会自动调用基类析构
};
#endif

 Cd.cpp
 

#define _CRT_SECURE_NO_WARNINGS 
#include"classic.h"

Cd::Cd(const char* s1,const char* s2, int n, double x)
{
	selections = n;
	playtime = x;
	strncpy(performers, s1, 49);
	strncpy(label, s2, 19);
	performers[49] = label[19] = '\0';
}

Cd_main.cpp

//不用对头文件定义该宏 因为头文件里面的函数定义都为内联函数,定义该宏vs不支持strncpy,strcpy函数
#define _CRT_SECURE_NO_WARNINGS 

#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();
	cout << endl;
	c2.Report();
	cout << endl;

	cout << "Using type cd * pointer to objects:\n";
	pcd->Report();
	cout << endl;
	pcd = &c2;
	pcd->Report();
	cout << endl;

	cout << "Calling a function with a Cd reference argument:\n";
	Bravo(c1);
	cout << endl;
	Bravo(c2);
	cout << endl;

	cout << "Testing assignment: ";
	Classic copy;
	copy = c2;
	copy.Report();

	return 0;
}

void Bravo(const Cd& disk)
{
	disk.Report();
}

输出结果

 

第二题

classic.h

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#ifndef CD_H_
#define CD_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&);
	Cd() { performers = nullptr; label = nullptr; selections = playtime = 0; }
	virtual ~Cd() { delete[]performers; delete[] label; }
	virtual void Report()const;
	Cd& operator=(const Cd&);
};

class Classic : public Cd
{
private:
	char* opus;
public:
	Classic() : Cd() { opus = nullptr; }
	Classic(const char* opus, const char* performers, const char* label,
		int selections, double playtime) : Cd(performers, label, selections, playtime)
	{
		this->opus = new char[strlen(opus) + 1];
		strcpy(this->opus, opus);
	}
	Classic(const Classic& cla) : Cd(cla)
	{
		opus = new char[strlen(cla.opus) + 1];
		strcpy(opus, cla.opus);
	}
	Classic& operator=(const Classic&);
	virtual void Report()const;
	virtual ~Classic() { delete[]opus; }
};
#endif

 classic.cpp

#define _CRT_SECURE_NO_WARNINGS
#include"classic.h"

using std::cout;
using std::endl;
//基类
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(const Cd& cd)
{
	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;
	playtime = cd.playtime;
}

void Cd::Report()const
{
	if (performers != nullptr && label != nullptr)
	{
		cout << "performers: " << performers << endl << "label: " << label << endl
			 << "selections: " << selections << endl << "playtime: " << playtime << endl;
	}
	else if (performers == nullptr)
	{
		cout << "performers: " << "(null)" << endl << "label: " << label << endl
			<< "selections: " << selections << endl << "playtime: " << playtime << endl;
	}
	else
	{
		cout << "performers: " << performers << endl << "label: " << "(null)" << endl
			 << "selections: " << selections << endl << "playtime: " << playtime << endl;
	}
	/*如果使用printf("str: ", performers)这种形式就不必写这些if 
	*str = NULL; printf("str: ", str) 输出空或者输出(null)*/
}

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;
	playtime = cd.playtime;

	return*this;
}
//派生类
Classic& Classic::operator=(const Classic& cla)
{
	if (this == &cla)
		return *this;
	Cd::operator=(cla);
	delete[]opus;
	opus = new char[strlen(cla.opus) + 1];
	strcpy(opus, cla.opus);

	return *this;
}

void Classic::Report()const
{
	Cd::Report();
	if (opus != nullptr)
		cout << "opus: " << opus << endl;
	else
		cout << "opus: " << "null\n";
}

class_main.cpp

//不用对头文件定义该宏 因为头文件里面的函数定义都为内联函数,定义该宏vs不支持strncpy,strcpy函数
#define _CRT_SECURE_NO_WARNINGS 

#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();
	cout << endl;
	c2.Report();
	cout << endl;

	cout << "Using type cd * pointer to objects:\n";
	pcd->Report();
	cout << endl;
	pcd = &c2;
	pcd->Report();
	cout << endl;


	cout << "Calling a function with a Cd reference argument:\n";
	Bravo(c1);
	cout << endl;
	Bravo(c2);
	cout << endl;

	cout << "Testing assignment: ";
	Classic copy;
	copy = c2;
	copy.Report();

	return 0;
}

void Bravo(const Cd& disk)
{
	disk.Report();
}

输出结果

第三题

dmaABC.h

#ifndef DMA_H_
#define DMA_H_
#include<iostream>

class dmaABC
{
private:
	char* label;
	int rating;
public:
	dmaABC(const char* l = "null", int r = 0)
	{
		label = new char[strlen(l) + 1];
		strcpy(label, l);
		rating = r;
	}
	dmaABC(const dmaABC& rs)
	{
		label = new char[strlen(rs.label) + 1];
		strcpy(label, rs.label);
		rating = rs.rating;
	}
	virtual ~dmaABC() { delete[]label; }
	dmaABC& operator=(const dmaABC& rs);
	virtual void View() const = 0;			//实现文件里完成
};

class baseDMA : public dmaABC
{
public:
	baseDMA(const char* l = "null", int r = 0) : dmaABC(l, r) { }
	baseDMA(const dmaABC& rs) : dmaABC(rs) { }
	virtual ~baseDMA() { }					//自动调用基类
	baseDMA& operator=(const baseDMA& rs) { dmaABC::operator=(rs); }
	virtual void View()const { dmaABC::View(); }
};

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) : dmaABC(l, r)
	{
		strncpy(color, c,COL_LEN - 1);
		color[COL_LEN - 1] = '\0';
	}
	lacksDMA(const char* c, const dmaABC& rs) : dmaABC(rs)
	{
		strncpy(color, c, COL_LEN - 1);
		color[COL_LEN - 1] = '\0';
	}

	virtual void View()const
	{
		dmaABC::View();
		std::cout << "color: " << color << std::endl;
	}
};

class hasDMA : public dmaABC
{
private:
	char* style;
public:
	hasDMA(const char* s = "none", const char* l = "null", int r = 0) : dmaABC(l, r)
	{
		style = new char[strlen(s) + 1];
		strcpy(style, s);
	}
	hasDMA(const char* s, const dmaABC& rs) : dmaABC(rs)
	{
		style = new char[strlen(s) + 1];
		strcpy(style, s);
	}
	hasDMA(const hasDMA& hs) : dmaABC(hs)
	{
		style = new char[strlen(hs.style) + 1];
		strcpy(style, hs.style);
	}

	virtual ~hasDMA() { delete[]style; }
	hasDMA& operator=(const hasDMA& rs);
	virtual void View()const
	{
		dmaABC::View();
		std::cout << "style: " << style << std::endl;
	}
};
#endif

 dmaABC.cpp

#define _CRT_SECURE_NO_WARNINGS
#include"dmaABC.h"

using std::cout;
using std::endl;

void dmaABC::View()const
{
	cout << "label: " << label << endl
		 << "rating: " << rating << endl;
}


dmaABC& dmaABC::operator=(const dmaABC& rs)
{
	if (this == &rs)
		return *this;
	delete[]label;
	label = new char[strlen(rs.label) + 1];
	strcpy(label, rs.label);
	rating = rs.rating;

	return*this;
}

hasDMA& hasDMA::operator=(const hasDMA& has)
{
	if (this == &has)
		return *this;
	dmaABC::operator=(has);
	delete[]style;
	style = new char[strlen(has.style) + 1];
	strcpy(style, has.style);

	return *this;
}

 main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"dmaABC.h"

const int SIZE(6);

int main()
{
	using std::cout;
	using std::endl;
	using std::cin;
	//dm_abc是个数组,该数组是个指针数组,该指针数组指向了dmaABC类 并没有创建dmaABC类
	dmaABC* dm_abc[SIZE];
	char label[40];
	int rating;
	char choice;

	for (int i = 0; i < SIZE; i++)
	{
		cout << "enter label: ";
		cin >> label;			//注意cin特性不可输入空 换行符
		cout << "enter rating: ";
		cin >> rating;
		cout << "1 or 2 or 3: ";//1 是baseDMA 2是lacksDMA 3是hasDMA
		while (cin >> choice && choice != '1'  && choice != '2' && choice != '3')
				continue;
		if (choice == '1')
		{
			dm_abc[i] = new baseDMA(label, rating);
		}
		else if (choice == '2')
		{
			char color[40];
			cout << "enter color: ";
			cin >> color;
			dm_abc[i] = new lacksDMA(color, label, rating);
		}
		else if (choice == '3')
		{
			char style[40];
			cout << "enter style: ";
			cin >> style;
			dm_abc[i] = new hasDMA(style, label, rating);
		}
		while (cin.get() != '\n')
			continue;
		cout << endl;
	}

	cout << "=======================================\n";
	for (int i = 0; i < SIZE; i++)
	{
		dm_abc[i]->View();
		cout << endl;
	}
	for (int i = 0; i < SIZE; i++)
		delete dm_abc[i];

	return 0;
}

输出结果

 第四题

 port.h

#define _CRT_SECURE_NO_WARNINGS
#ifndef PORT_H_
#define PORT_H_

#include<iostream>
using namespace std;
class Port
{
private:
	char* brand;
	char style[20];
	int bottles;
public:
	Port(const char* br = "none", const char* st = "none", int b = 0);
	Port(const Port& p);
	virtual ~Port() { delete[]brand; }
	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);
};

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() { delete[]nickname; }
	VintagePort& operator=(const VintagePort& vp);
	void Show()const;
	friend ostream& operator<<(ostream& os, const VintagePort& vp);
};
#endif

port.cpp

#define _CRT_SECURE_NO_WARNINGS

#include"port.h"
//基类定义
Port::Port(const char* br, const char* st, int b)
{
	brand = new char[strlen(br) + 1];
	strcpy(brand, br);
	strncpy(style, st, 19);
	style[19] = '\0';
	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::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)
{
	if (bottles - b >= 0)
		bottles -= b;
	else
		cout << "Not enough quantity\n";
	return*this;
}

void Port::Show()const
{
	cout << "Brand: " << brand << endl
		 << "Kind: " << style << endl
		 << "Bottles: " << bottles << endl;
}

ostream& operator<<(ostream& os, const Port& p)
{
	os << p.brand << ", " << p.style << ", " << p.bottles;
	return os;
}

//派生类
VintagePort::VintagePort() : Port()
{
	nickname = nullptr;
	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)
{
	nickname = new char[strlen(vp.nickname) + 1];
	strcpy(nickname, vp.nickname);
	year = vp.year;
}

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();
	if (nickname != nullptr)
		cout << "nickname: " << nickname << endl
			 << "year: " << year << endl;
}

ostream& operator<<(ostream& os, const VintagePort& vp)
{
	cout << (const Port&)vp;
	if(vp.nickname != nullptr)
		cout << ", " << vp.nickname
   			 << ", " << vp.year;
	return os;
}

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include"port.h"
#include<iostream>
int main()
{
	Port po("Gallo", "tawny", 20);

	cout << "Port::operator<<():\n";
	cout << po;
	cout << endl << endl;

	cout << "Port::Show():\n";
	po.Show();

	cout << "\nPort::Show():\n";
	po -= 20;
	po.Show();
	cout << '\n';
	po += 10;
	po -= 20;
	cout << "\nPort::Show():\n";
	po.Show();
	Port port(po);
	cout << "\nPort Show():\n";
	port.Show();

	VintagePort vin_po;

	cout << "\nVintagePort::Show():\n";	//注意这里显示没有错误,没有添加为nullptr的显示
	vin_po.Show();
	vin_po = VintagePort("Gallo", 10, "bai", 2012); //先调用复制在调用赋值\

	cout << endl;
	cout << "\nVintagePort::operator<<():";
	cout << endl << vin_po;

	VintagePort vin = vin_po;
	cout << "\n\nVintagePort::Show():\n";
	vin.Show();

	cout << "\nVintagePort::Show():\n";
	vin_po -= 10;
	vin_po.Show();

	VintagePort tage(vin_po);
	cout << "\nVintagePort::Show():";
	tage.Show();

	return 0;
}

输出结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值