C ++ Primer Plus 第六版 第十三章编程练习答案

1.以下面的类声明为基础:
// base class
class Cd { //represents a CD disk
private:
char performers[50];
char label[20];
int selections; //number of selections
double playtime; //playing time in minute
public:
Cd(char * s1, char * s2, int n, double x);
Cd(const Cd & d);
Cd();
~Cd();
void Report() const; //reports all CD data
Cd & operator=(const Cd & d);
};
派生出一个Classic类,并添加一组char成员,用于存储指出CD中主要作品的字符串。修改上述声明,使基类的搜有函数都是虚的。如果上述定义声明的某个方法并不需要,则请删除它。使用下面的程序测试您的产品:
#include<iostream>
using namespace std;
#include"classic.h" //which will contain #include cd.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(); //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();
 
return 0;
}
 
void Bravo(const Cd& disk)
{
disk.Report();

}

//cd.h
#ifndef CD_H_INCLUDED
#define CD_H_INCLUDED

class Cd
{
private:
	char performers[50];
	char label[20];
	int selections;
	double playtime;
public:
	Cd ( char *s1, char *s2, int n, double x );
	Cd ( const Cd & d );
	Cd();
	virtual ~Cd();
	virtual void Report() const;
	virtual Cd & operator= ( const Cd & d );

};

class Classic: public Cd
{
private:
	char opus[100];
public:
	Classic();
	Classic ( const Classic & c );
	Classic (  char * o, char *s1, char *s2, int n, double x );
	~Classic();
	virtual void Report() const;
	virtual Cd & operator= ( const Classic & c );
};
#endif // CD_H_INCLUDED
//cd.cpp
#include <iostream>
#include<cstring>
#include"cd.h"
using std::strcpy;
using std::cout;
using std::cin;
using std::endl;


Cd::Cd ( char *s1, char *s2, int n, double x )
{
	strcpy ( performers, s1 );
	strcpy ( label, s2 );
	selections = n;
	playtime = x;
}

Cd::Cd ( const Cd & d )
{
	strcpy ( performers, d.performers );
	strcpy ( label, d.label );
	selections = d.selections;
	playtime = d.playtime;
}

Cd::Cd()
{
	strcpy ( performers, "NULL" );
	strcpy ( label, "NULL" );
	selections = 0;
	playtime = 0;
}

Cd::~Cd() {}

void Cd::Report() const
{
	cout << "performers: " << performers << endl;
	cout << "label: " << label << endl;
	cout << "selections: " << selections << endl;
	cout << "playtime: " << playtime << endl;
}

Cd & Cd::operator= ( const Cd & d )
{
	strcpy ( performers, d.performers );
	strcpy ( label, d.label );
	selections = d.selections;
	playtime = d.playtime;
	return *this;
}

Classic::Classic() : Cd()
{
	strcpy ( opus, "NULL" );
}

Classic::Classic ( const Classic & c ) : Cd ( c )
{
	strcpy ( opus, c.opus );
}

Classic::Classic ( char * o, char *s1, char *s2, int n, double x ) : Cd ( s1, s2, n, x )
{
	strcpy ( opus, o );
}

Classic::~Classic() {}

void Classic::Report() const
{
	Cd::Report();
	cout << "opus: " << opus << endl;

}

Cd & Classic::operator= ( const Classic & c )
{
	if ( this == &c )
		return *this;
	Cd::operator= ( c );
	strcpy ( opus, c.opus );
	return *this;
}
//main.cpp
#include <iostream>
#include"cd.cpp"
#include"cd.h"

void Bravo ( const Cd& disk );
int main()
{
	using namespace std;
	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
	cout << endl;
	     c2.Report();        //use Classic method
	cout << endl;
	     cout << "Using type cd *pointer to objects:\n";
	pcd->Report();   //use Cd method for cd object
	cout << endl;
	     pcd = &c2;
	pcd->Report();   //use Classic method for classic object
	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();
	cout << endl;
	     system ( "pause" );
	return 0;
}

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

2.完成练习1,但让两个类使用动态内存分配而不是长度固定的数组来记录字符串。
#ifndef CD_H_INCLUDED
#define CD_H_INCLUDED

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;
	virtual Cd & operator= ( const Cd & d );

};

class Classic: public Cd
{
private:
	char *opus;
public:
	Classic();
	Classic ( const Classic & c );
	Classic (  const char * o, const char *s1, const char *s2, int n, double x );
	~Classic();
	virtual void Report() const;
	virtual Cd & operator= ( const Classic & c );
};
#endif // CD_H_INCLUDED
#include <iostream>
#include<cstring>
#include"cd.h"
using std::strcpy;
using std::strlen;
using std::cout;
using std::cin;
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 & 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()
{
	performers=new char[1];
	label=new char[1];
	performers[0]='\0';
	label[0]='\0';
	selections = 0;
	playtime = 0;
}

Cd::~Cd()
{
	delete []performers;
	delete []label;
}

void Cd::Report() const
{
	cout << "performers: " << performers << endl;
	cout << "label: " << label << endl;
	cout << "selections: " << selections << endl;
	cout << "playtime: " << playtime << endl;
}

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

Classic::Classic() : Cd()
{
	opus=new char[1];
	opus[0]='\0';
}

Classic::Classic ( const Classic & c ) : Cd ( c )
{
	opus=new char[strlen(c.opus)+1];
	strcpy ( opus, c.opus );
}

Classic::Classic (const  char * o,const  char *s1, const char *s2, int n, double x ) : Cd ( s1, s2, n, x )
{
	opus=new char[strlen(o)+1];
	strcpy ( opus, o );
}

Classic::~Classic()
{
	delete []opus;
}

void Classic::Report() const
{
	Cd::Report();
	cout << "opus: " << opus << endl;

}

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

4.Benevolent Order of Programmers用来维护瓶装葡萄酒箱。为描述它,BOP Portmaster设置了一个Port类,并声明如下:
#include<iostream>
using namespace std;
class Port
{
private:
char * brand;
char style[20]; //i.e., tawny, ruby, vintage
int bottles;
public:
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);
Port & operator+=(int b); //add b to bottles
Port & operator-=(int b); //subtracts b from bottles , if available
int BottleCount() const {return bottles; ]
virtual void Show() const;
friend ostream & operator<<(ostream & os, const Port &p);
};
show()方法按下面的格式显示信息:
Brand: Gallo
Kind: tawny
Bottles: 20
operator<<()函数按下面的格式显示信息(末尾没有换行符):
Gallo, tawny, 20
PortMaster完成了Port类的方法定义后派生了VintagePort类,然后被解职——因为不小心将一瓶45度Cockburn泼到了正在准备烤肉调料的人身上,VintagePort类如下显示:
class VintagePort: public Port //style necessarily = "vintage"
{
private:
char * nickname; //i.e. , "The Noble" or "Old Velvet", etc.
int year; //vintage year
public:
VintagePort();
VintagePort(const char * br, const char *st, int b, const char * nn, int y);
//注:我认为上面这个构造函数少了一个st字符串,这个字符串是用于给style字符串赋值的
VintagePort(const VintagePort & vp);
~VintagePort() { delete [] nickname; }
VintagePort & operator = (const VintagePort & vp);
void show() const;
friend ostream & operator <<(ostream & os, const VintagePort &vp);
};
您被制定指定负责完成VintagePort。
a。第一个任务是重新创建Port方法定义,因为前任被开除时销毁了方法定义。
b。第二个任务是解释为什么有的方法重新定义了,而有些没有重新定义。
c。第三个任务解释为何没有将operator=() 和operator<<()声明为虚的。
d。第四个任务是提供VintagePort中各个方法的定义。
 
答:
②对于基类的虚函数,有必要重新定义;
③因为赋值运算符和友元函数不能被继承;

#ifndef PORT_H_INCLUDED
#define PORT_H_INCLUDED
#include <iostream>
using std::cout;
using std::ostream;
class Port
{
private:
    char * brand;
    char style[20]; //i.e., tawny, ruby, vintage
    int bottles;
public:
    Port(const char * br = "none", const char *st = "none", int b = 0);
    Port(const Port & p);       //cpoy constructor
    virtual ~Port() { delete[] brand; }
    Port & operator=(const Port&p);
    Port & operator+=(int b);       //add b to bottles
    Port & operator-=(int b);       //subtracts b from bottles , if available
    int BottleCount() const { return bottles; }
    virtual void Show() const;
    friend ostream & operator<<(ostream & os, const Port &p);
};

class VintagePort : public Port     //style necessarily = "vintage"
{
private:
    char * nickname;        //i.e. , "The Noble" or "Old Velvet", etc.
    int year;               //vintage year
public:
    VintagePort();
    VintagePort(const char * br, const char *st, int b, const char * nn, int y);
    VintagePort(const VintagePort & vp);
    ~VintagePort() { delete[] nickname; }
    VintagePort & operator = (const VintagePort & vp);
    virtual void Show() const;
    friend ostream & operator <<(ostream & os, const VintagePort &vp);
};


#endif // PORT_H_INCLUDED


#include <iostream>
#include<cstring>
#include"port.h"
using namespace std;
Port::Port ( const char * br, const char *st, int b )
{
	int len = strlen ( br );
	brand = new char[len + 1];
	strcpy ( brand, br );
	strcpy ( style, st );
	bottles = b;
}
Port::Port ( const Port & p )
{
	int len = strlen ( p.brand );
	brand = new char[len + 1];
	strcpy ( brand, p.brand );
	strcpy ( style, p.style );
	bottles = p.bottles;
}


Port &  Port::operator= ( const Port & p )
{
	delete [] brand;
	int len = strlen ( p.brand );
	brand = new char[len + 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::VintagePort() : Port()
{
	nickname = new char[1];
	nickname[0] = '\0';
	year = 0;
}

VintagePort::VintagePort ( const char * br, const char *st, int b, const char * nn, int y ) : Port ( br, st, b )
{
	int len = strlen ( nn );
	nickname = new char[len + 1];
	strcpy ( nickname, nn );
	year=y;
}

VintagePort::VintagePort ( const VintagePort & vp ) : Port ( vp )
{
	int len = strlen ( vp.nickname );
	nickname = new char[len + 1];
	strcpy ( nickname, vp.nickname );
	year = vp.year;
}

VintagePort & VintagePort::operator = ( const VintagePort & vp )
{
	if ( this == &vp )
		return *this;
	Port::operator= ( vp );
	delete []nickname;
	int len = strlen ( vp.nickname );
	nickname = new char[len + 1];
	strcpy ( nickname, vp.nickname );
	year = vp.year;
	return *this;
}

void VintagePort::Show() const
{
	Port::Show();
	cout << "Nickname: " << nickname << endl;
	cout << "Year: " << year << endl;
}

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




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值