网站建设方案评标原则,小榄网站建设推广,亚马逊站外推广网站,长春快速建站公司《C Primer Plus》#xff08;第6版#xff09;第13章编程练习《C Primer Plus》#xff08;第6版#xff09;第13章编程练习1. Cd类2. 使用动态内存分配重做练习13. baseDMA、lacksDMA、hasDMA类4. Port类和VintagePort类《C Primer Plus》#xff08;第6版#xff09;第…
《C Primer Plus》第6版第13章编程练习《C Primer Plus》第6版第13章编程练习1. Cd类2. 使用动态内存分配重做练习13. baseDMA、lacksDMA、hasDMA类4. Port类和VintagePort类《C Primer Plus》第6版第13章编程练习
1. Cd类
以下面的类声明为基础
class Cd { //represents a CD disk
private:char performers[50];char label[20];int selections; //number of selectionsdouble 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 dataCd operator(const Cd d);
};派生出一个Classic类并添加一组char成员用于存储指出CD中主要作品的字符串。修改上述声明使基类的搜有函数都是虚的。如果上述定义声明的某个方法并不需要则请删除它。使用下面的程序测试您的产品
#includeiostream
using namespace std;
#includeclassic.hvoid 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 methodc2.Report(); //use Classic methodcout Using type cd *pointer to objects:\n;pcd-Report(); //use Cd method for cd objectpcd c2;pcd-Report(); //use Classic method for classic objectcout 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_
#define CD_H_class Cd
{ // represents a CD disk
private:char performers[50];char label[20];int selections; // number of selectionsdouble playtime; // playing time in minutepublic:Cd(char *s1, char *s2, int n, double x);Cd(const Cd d);Cd();virtual ~Cd();virtual void Report() const; // reports all CD datavirtual Cd operator(const Cd d);
};#endifcd.cpp
#include cd.h
#include iostream
#include cstringCd::Cd(char *s1, char *s2, int n, double x)
{strncpy(performers, s1, 49);performers[49] \0;strncpy(label, s2, 19);label[19] \0;selections n;playtime x;
}
Cd::Cd(const Cd d)
{strncpy(performers, d.performers, 49);performers[49] \0;strncpy(label, d.label, 19);label[19] \0;selections d.selections;playtime d.playtime;
}
Cd::Cd()
{performers[0] \0;label[0] \0;selections 0;playtime 0.0;
}
Cd::~Cd()
{
}
void Cd::Report() const
{using std::cout;using std::endl;cout Information:\n;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;strncpy(performers, d.performers, 49);performers[49] \0;strncpy(label, d.label, 19);label[19] \0;selections d.selections;playtime d.playtime;return *this;
}classic.h
#ifndef CLASSIC_H_
#define CLASSIC_H_#include cd.hclass Classic : public Cd
{
private:char majorWorks[50];public:Classic(char *m, char *s1, char *s2, int n, double x);Classic(char *m, const Cd cd);Classic();virtual ~Classic();virtual void Report() const;virtual Classic operator(const Classic c);
};#endifclassic.cpp
#include classic.h
#include iostream
#include cstringClassic::Classic(char *m, char *s1, char *s2, int n, double x) : Cd(s1, s2, n, x)
{strncpy(majorWorks, m, 49);majorWorks[49] \0;
}
Classic::Classic(char *m, const Cd cd) : Cd(cd)
{strncpy(majorWorks, m, 49);majorWorks[49] \0;
}
Classic::Classic() : Cd()
{majorWorks[0] \0;
}
Classic::~Classic()
{
}
void Classic::Report() const
{using std::cout;using std::endl;Cd::Report();cout Major works: majorWorks endl;
}
Classic Classic::operator(const Classic c)
{if (this c)return *this;Cd::operator(c);strncpy(majorWorks, c.majorWorks, 49);majorWorks[49] \0;return *this;
}main.cpp
#include iostream
using namespace std;
#include classic.hvoid 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 methodc2.Report(); // use Classic methodcout Using type cd *pointer to objects:\n;pcd-Report(); // use Cd method for cd objectpcd c2;pcd-Report(); // use Classic method for classic objectcout Calling a function with a Cd reference argument:\n;Bravo(c1);Bravo(c2);cout Testing assignment: ;Classic copy;copy c2;copy.Report();system(pause);return 0;
}void Bravo(const Cd disk)
{disk.Report();
}运行结果
Microsoft Windows [版本 10.0.19044.2728]
(c) Microsoft Corporation。保留所有权利。C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.1g cd.cpp classic.cpp main.cpp -o main
main.cpp: In function int main():
main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Cd c1(beatles, Capitol, 14, 35.5);^
main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);^
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.1main
Using object directly:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Using type cd *pointer to objects:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Calling a function with a Cd reference argument:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Testing assignment: Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.12. 使用动态内存分配重做练习1
完成练习1但让两个类使用动态内存分配而不是长度固定的数组来记录字符串。
代码
cd.h
#ifndef CD_H_
#define CD_H_class Cd
{ // represents a CD disk
private:char *performers;char *label;int selections; // number of selectionsdouble playtime; // playing time in minutepublic:Cd(char *s1, char *s2, int n, double x);Cd(const Cd d);Cd();virtual ~Cd();virtual void Report() const; // reports all CD datavirtual Cd operator(const Cd d);
};#endifcd.cpp
#include cd.h
#include iostream
#include cstring
using std::strcpy;
using std::strlen;Cd::Cd(char *s1, char *s2, int n, double x)
{performers new char[strlen(s1) 1];strcpy(performers, s1);label new char[strlen(s2) 1];strcpy(label, s2);selections n;playtime x;
}
Cd::Cd(const Cd d)
{performers new char[strlen(d.performers) 1];strcpy(performers, d.performers);label new char[strlen(d.label) 1];strcpy(label, d.label);selections d.selections;playtime d.playtime;
}
Cd::Cd()
{performers new char[1];strcpy(performers, \0);label new char[1];strcpy(label, \0);selections 0;playtime 0.0;
}
Cd::~Cd()
{delete[] performers;delete[] label;
}
void Cd::Report() const
{using std::cout;using std::endl;cout Information:\n;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];strcpy(performers, d.performers);label new char[strlen(d.label) 1];strcpy(label, d.label);selections d.selections;playtime d.playtime;return *this;
}classic.h
#ifndef CLASSIC_H_
#define CLASSIC_H_#include cd.hclass Classic : public Cd
{
private:char *majorWorks;public:Classic(char *m, char *s1, char *s2, int n, double x);Classic(char *m, const Cd cd);Classic();virtual ~Classic();virtual void Report() const;virtual Classic operator(const Classic c);
};#endifclassic.cpp
#include classic.h
#include iostream
#include cstring
using std::strcpy;
using std::strlen;Classic::Classic(char *m, char *s1, char *s2, int n, double x) : Cd(s1, s2, n, x)
{majorWorks new char[strlen(m) 1];strcpy(majorWorks, m);
}
Classic::Classic(char *m, const Cd cd) : Cd(cd)
{majorWorks new char[strlen(m) 1];strcpy(majorWorks, m);
}
Classic::Classic() : Cd()
{majorWorks new char[1];strcpy(majorWorks, \0);
}
Classic::~Classic()
{delete[] majorWorks;
}
void Classic::Report() const
{using std::cout;using std::endl;Cd::Report();cout Major works: majorWorks endl;
}
Classic Classic::operator(const Classic c)
{if (this c)return *this;Cd::operator(c);majorWorks new char[strlen(c.majorWorks) 1];strcpy(majorWorks, c.majorWorks);return *this;
}main.cpp与练习1的main.cpp相同。
运行结果
C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.2g cd.cpp classic.cpp main.cpp -o main
main.cpp: In function int main():
main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Cd c1(beatles, Capitol, 14, 35.5);^
main.cpp:9:41: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]Classic c2 Classic(Piano Sonata in B flat, Fantasia in C, Alfred Brendel, Philips, 2, 57.17);^
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]
main.cpp:10:104: warning: ISO C forbids converting a string constant to char* [-Wwrite-strings]C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.2main
Using object directly:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Using type cd *pointer to objects:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Calling a function with a Cd reference argument:
Information:
Performers: beatles
Label: Capitol
Selections: 14
Playtime: 35.5
Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
Testing assignment: Information:
Performers: Alfred Brendel
Label: Philips
Selections: 2
Playtime: 57.17
Major works: Piano Sonata in B flat, Fantasia in C
请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.23. baseDMA、lacksDMA、hasDMA类
修改baseDMA-lacksDMA-hasDMA类层次让三个类都从一个ABC派生而来然后使用与程序清单13.10相似的程序对结果进行测试。也就是说它应使用ABC指针数组并让用户决定要创建的对象类型。在类定义中添加virtual View()方法以处理数据显示。
代码
dma.h
#ifndef DMA_H_
#define DMA_H_#include iostreamclass ABC
{
public:ABC(){};~ABC(){};virtual void View() 0;
};class baseDMA : public ABC
{
private:char *label;int rating;public:baseDMA(const char *l null, int r 0);baseDMA(const baseDMA rs);virtual ~baseDMA();baseDMA operator(const baseDMA rs);friend std::ostream operator(std::ostream os, const baseDMA rs);virtual void View();
};class lacksDMA : public baseDMA
{
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 baseDMA rs);friend std::ostream operator(std::ostream os, const lacksDMA rs);virtual void View();
};
class hasDMA : public baseDMA
{
private:char *style;public:hasDMA(const char *s none, const char *l null, int r 0);hasDMA(const char *s, const baseDMA rs);hasDMA(const hasDMA hs);~hasDMA();hasDMA operator(const hasDMA hs);friend std::ostream operator(std::ostream os, const hasDMA hs);virtual void View();
};#endifdma.cpp
#include dma.h
#include iostream
#include cstring
using std::cout;
using std::endl;
using std::strcpy;
using std::strlen;
using std::strncpy;// baseDMA methods
baseDMA::baseDMA(const char *l, int r)
{label new char[strlen(l) 1];strcpy(label, l);rating r;
}
baseDMA::baseDMA(const baseDMA rs)
{label new char[strlen(rs.label) 1];strcpy(label, rs.label);rating rs.rating;
}
baseDMA::~baseDMA()
{delete[] label;
}
baseDMA baseDMA::operator(const baseDMA rs)
{if (this rs)return *this;delete[] label;label new char[strlen(rs.label) 1];strcpy(label, rs.label);rating rs.rating;return *this;
}
std::ostream operator(std::ostream os, const baseDMA rs)
{os Label: rs.label endl;os Rating: rs.rating endl;return os;
}
void baseDMA::View()
{cout Label: label endl;cout Rating: rating endl;
}// lacksDMA methods
lacksDMA::lacksDMA(const char *c, const char *l, int r) : baseDMA(l, r)
{strncpy(color, c, 39);color[39] \0;
}
lacksDMA::lacksDMA(const char *c, const baseDMA rs) : baseDMA(rs)
{strncpy(color, c, COL_LEN - 1);color[COL_LEN - 1] \0;
}
std::ostream operator(std::ostream os, const lacksDMA ls)
{os (const baseDMA )ls;os Color: ls.color endl;return os;
}
void lacksDMA::View()
{baseDMA::View();cout Color: color endl;
}// hasDMA methods
hasDMA::hasDMA(const char *s, const char *l, int r) : baseDMA(l, r)
{style new char[strlen(s) 1];strcpy(style, s);
}
hasDMA::hasDMA(const char *s, const baseDMA rs) : baseDMA(rs)
{style new char[strlen(s) 1];strcpy(style, s);
}
hasDMA::hasDMA(const hasDMA hs) : baseDMA(hs)
{style new char[strlen(hs.style) 1];strcpy(style, hs.style);
}
hasDMA::~hasDMA()
{delete[] style;
}
hasDMA hasDMA::operator(const hasDMA hs)
{if (this hs)return *this;baseDMA::operator(hs);delete[] style;style new char[strlen(hs.style) 1];strcpy(style, hs.style);return *this;
}
std::ostream operator(std::ostream os, const hasDMA hs)
{os (const baseDMA )hs;os Style: hs.style endl;return os;
}
void hasDMA::View()
{baseDMA::View();cout Style: style endl;
}main.cpp
#include dma.h
#include iostream
#include string
using namespace std;int main()
{int n;cout How many DMAs do you have? ;cin n;ABC *p_dma[n];char *t_label new char[50];int t_rating;int kind;for (int i 0; i n; i){cout Enter label: ;cin.getline(t_label, 50);cout Enter rating: ;cin t_rating;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.ignore();switch (kind){case 1:p_dma[i] new baseDMA(t_label, t_rating);break;case 2:char t_color[40];cout Enter color: ;cin.getline(t_color, 40);p_dma[i] new lacksDMA(t_color, t_label, t_rating);break;case 3:char *t_style new char[20];cout Enter style: ;cin.getline(t_style, 20);p_dma[i] new hasDMA(t_style, t_label, t_rating);break;}while (cin.get() ! \n)continue;}cout endl;for (int i 0; i n; i){p_dma[i]-View();cout endl;}for (int i 0; i n; i){delete p_dma[i];}cout Done.\n endl;system(pause);return 0;
}运行结果
Microsoft Windows [版本 10.0.19044.2728]
(c) Microsoft Corporation。保留所有权利。C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.3g dma.cpp main.cpp -o mainC:\Users\81228\Documents\Program\VScode C Program\chapter13\13.3main
Enter label: Portabelly
Enter rating: 8
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: Blimpo
Enter rating: 4
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 2
Enter color: redEnter label: Buffalo Keys
Enter rating: 5
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 3
Enter style: MercatorEnter label: lable1
Enter rating: 10
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: lable2
Enter rating: 3
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 1Enter label: lable3
Enter rating: 1
Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: 9
Enter either 1 or 2 or 3: 1Label: Portabelly
Rating: 8Label: Blimpo
Rating: 4
Color: redLabel: Buffalo Keys
Rating: 5
Style: MercatorLabel: lable1
Rating: 10Label: lable2
Rating: 3Label: lable3
Rating: 1Done.请按任意键继续. . .C:\Users\81228\Documents\Program\VScode C Program\chapter13\13.34. Port类和VintagePort类
Benevolent Order of Programmers用来维护瓶装葡萄酒箱。为描述它BOP Portmaster设置了一个Port类并声明如下
#include iostream
using namespace std;
class Port
{
private:char *brand;char style[20]; // i.e., tawny, ruby, vintageint bottles;public:Port(const char *br none, const char *st none, int b 0);Port(const Port p); // copy constructorvirtual ~Port() { delete[] brand; }Port operator(const Port p);Port operator(int b); // add b to bottlesPort operator-(int b); // subtracts b from bottles , if availableint BottleCount() const { return bottles; }virtual void Show() const;friend ostream operator(ostream os, const Port p);
};show()方法按下面的格式显示信息
Brand : Gallo
Kind : tawny
Bottles : 20operator()函数按下面的格式显示信息末尾没有换行符
Gallo, tawny, 20PortMaster完成了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);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中各个方法的定义。
答
a.第一个任务是重新创建Port方法定义因为前任被开除时销毁了方法定义。
#include port.h
#include iostream
#include cstring
using namespace std;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) // copy constructor
{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) // add b to bottles
{bottles b;return *this;
}
Port Port::operator-(int b) // subtracts b from bottles , if available
{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;
}b.第二个任务是解释为什么有的方法重新定义了而有些没有重新定义。 当派生类成员函数需要处理派生类独有的成员变量时需要重新定义方法如果不需要处理派生类独有的成员变量直接调用基类的方法即可。 c.第三个任务解释为何没有将operator () 和operator ()声明为虚的。 a).如果要在派生类中重新定义基类的方法则将它设置为虚方法。但是基类的operator () 和派生类的operator () 形参不一样根本不是一个类方法不存在重新定义的问题因从也不必声明为虚的。 b).operator()函数是友元函数友元函数不能是虚函数因为友元不是类成员而只有类成员才能是虚函数。 d.第四个任务是提供VintagePort中各个方法的定义。
#include VintagePort.h
#include iostream
#include cstring
using namespace std;VintagePort::VintagePort() : Port()
{
}
VintagePort::VintagePort(const char *br, const char *st, int b, const char *nn, int y) : Port(br, st, b)
{nickname new char[strlen(nn) 1];strcpy(nickname, nn);int year y;
}
VintagePort::VintagePort(const VintagePort vp) : Port(vp)
{nickname new char[strlen(vp.nickname) 1];strcpy(nickname, vp.nickname);int 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);strcpy(nickname, vp.nickname);year vp.year;return *this;
}
void VintagePort::show() const
{Port::Show();cout Nick Name: nickname endl;cout Year: year endl;
}
ostream operator(ostream os, const VintagePort vp)
{os (const Port )vp;os vp.nickname , vp.year;return os;
}