当前位置: 首页 > news >正文

C++ Primer Plus 第六版 第十三章 编程题

1.以下面的类声明为基础:

//base class
class Cd { //represents a CD disk
private:char performers[50];char label[20];int selections;//number of selectionsdouble playtime;//playing time in minutes
public:Cd(char * sl, 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 中主要作品的字符串。修改上述声明,使基类的所有函数都是虚的。如果上述定义声明的某个方法并不需要,则请删除它。使用下面的程序测试您的产品:

#include <iostream>
using namespace std;
#include "classic.h"    //which will contain #include cd.h
void Bravo(const Cd & disk);
int main()
{Cd cl("Beatles", "Capitol",14,35.5);Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C", "Alfred Brendel","Philips",2,57.17);Cd *pcd = &cl;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

// cd.h -- Cd class declaration
#ifndef CD_H_
#define CD_H_// base class
class Cd { // represents a CD disk
private:char performers[50];char label[20];int selections; // number of selectionsdouble playtime; // playing time in minutes
public:Cd(const char * s1, const 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);
};#endif

cd.cpp

// cd.cpp -- Cd class implementation
#include <iostream>
#include <cstring>
#include "cd.h"// Constructor
Cd::Cd(const char * s1, const char * s2, int n, double x) {strncpy(performers, s1, 49);performers[49] = '\0';strncpy(label, s2, 19);label[19] = '\0';selections = n;playtime = x;
}// Copy constructor
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;
}// Default constructor
Cd::Cd() {performers[0] = '\0';label[0] = '\0';selections = 0;playtime = 0.0;
}// Report method
void Cd::Report() const {std::cout << "Performers: " << performers << std::endl;std::cout << "Label: " << label << std::endl;std::cout << "Selections: " << selections << std::endl;std::cout << "Playtime: " << playtime << " minutes" << std::endl;
}// Assignment operator
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

// classic.h -- Classic class declaration
#ifndef CLASSIC_H_
#define CLASSIC_H_
#include "cd.h"class Classic : public Cd {
private:char mainworks[100];
public:Classic(const char * works, const char * s1, const char * s2, int n, double x);Classic();Classic(const Classic & c);virtual ~Classic() {}virtual void Report() const;virtual Classic & operator=(const Classic & c);
};#endif

classic.cpp

// classic.cpp -- Classic class implementation
#include <iostream>
#include <cstring>
#include "classic.h"// Constructor
Classic::Classic(const char * works, const char * s1, const char * s2, int n, double x): Cd(s1, s2, n, x) {strncpy(mainworks, works, 99);mainworks[99] = '\0';
}// Default constructor
Classic::Classic() : Cd() {mainworks[0] = '\0';
}// Copy constructor
Classic::Classic(const Classic & c) : Cd(c) {strncpy(mainworks, c.mainworks, 99);mainworks[99] = '\0';
}// Report method
void Classic::Report() const {Cd::Report();std::cout << "Main works: " << mainworks << std::endl;
}// Assignment operator
Classic & Classic::operator=(const Classic & c) {if (this == &c)return *this;Cd::operator=(c);strncpy(mainworks, c.mainworks, 99);mainworks[99] = '\0';return *this;
}

usecd.cpp

// usecd.cpp -- testing Cd and Classic classes
#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();  // 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();
}

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

cd_dynamic.h

// cd_dynamic.h -- Cd class declaration with dynamic memory
#ifndef CD_DYNAMIC_H_
#define CD_DYNAMIC_H_// base class
class Cd { // represents a CD disk
private:char * performers;char * label;int selections; // number of selectionsdouble playtime; // playing time in minutes
public:Cd(const char * s1, const 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);
};#endif

cd_dynamic.cpp

// cd_dynamic.cpp -- Cd class implementation with dynamic memory
#include <iostream>
#include <cstring>
#include "cd_dynamic.h"// Constructor
Cd::Cd(const char * s1, const 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;
}// Copy constructor
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;
}// Default constructor
Cd::Cd() {performers = new char[1];performers[0] = '\0';label = new char[1];label[0] = '\0';selections = 0;playtime = 0.0;
}// Destructor
Cd::~Cd() {delete [] performers;delete [] label;
}// Report method
void Cd::Report() const {std::cout << "Performers: " << performers << std::endl;std::cout << "Label: " << label << std::endl;std::cout << "Selections: " << selections << std::endl;std::cout << "Playtime: " << playtime << " minutes" << std::endl;
}// Assignment operator
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_dynamic.h

// classic_dynamic.h -- Classic class declaration with dynamic memory
#ifndef CLASSIC_DYNAMIC_H_
#define CLASSIC_DYNAMIC_H_
#include "cd_dynamic.h"class Classic : public Cd {
private:char * mainworks;
public:Classic(const char * works, const char * s1, const char * s2, int n, double x);Classic();Classic(const Classic & c);virtual ~Classic();virtual void Report() const;virtual Classic & operator=(const Classic & c);
};#endif

classic_dynamic.cpp

// classic_dynamic.cpp -- Classic class implementation with dynamic memory
#include <iostream>
#include <cstring>
#include "classic_dynamic.h"// Constructor
Classic::Classic(const char * works, const char * s1, const char * s2, int n, double x): Cd(s1, s2, n, x) {mainworks = new char[strlen(works) + 1];strcpy(mainworks, works);
}// Default constructor
Classic::Classic() : Cd() {mainworks = new char[1];mainworks[0] = '\0';
}// Copy constructor
Classic::Classic(const Classic & c) : Cd(c) {mainworks = new char[strlen(c.mainworks) + 1];strcpy(mainworks, c.mainworks);
}// Destructor
Classic::~Classic() {delete [] mainworks;
}// Report method
void Classic::Report() const {Cd::Report();std::cout << "Main works: " << mainworks << std::endl;
}// Assignment operator
Classic & Classic::operator=(const Classic & c) {if (this == &c)return *this;Cd::operator=(c);delete [] mainworks;mainworks = new char[strlen(c.mainworks) + 1];strcpy(mainworks, c.mainworks);return *this;
}


3.修改 baseDMA-acksDMA-hasDMA 类层次,让三个类都从一个 ABC派生而来,然后使用与程序清单 13.10相似的程序对结果进行测试。也就是说,它应使用ABC指针数组,并让用户决定要创建的对象类型。在类定义中添加 virtual View()方法以处理数据显示。

abcDMA.h

// abcDMA.h -- ABC DMA classes
#ifndef ABCDMA_H_
#define ABCDMA_H_
#include <iostream>// ABC DMA class
class ABCDMA {
private:char * label;int rating;
public:ABCDMA(const char * l = "null", int r = 0);ABCDMA(const ABCDMA & rs);virtual ~ABCDMA();ABCDMA & operator=(const ABCDMA & rs);virtual void View() const = 0;  // pure virtual functionfriend std::ostream & operator<<(std::ostream & os, const ABCDMA & rs);
};// baseDMA class
class baseDMA : public ABCDMA {
public:baseDMA(const char * l = "null", int r = 0);baseDMA(const baseDMA & rs);virtual ~baseDMA() {}baseDMA & operator=(const baseDMA & rs);virtual void View() const;friend std::ostream & operator<<(std::ostream & os, const baseDMA & rs);
};// lacksDMA class
class lacksDMA : public ABCDMA {
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 ABCDMA & rs);virtual void View() const;friend std::ostream & operator<<(std::ostream & os, const lacksDMA & rs);
};// hasDMA class
class hasDMA : public ABCDMA {
private:char * style;
public:hasDMA(const char * s = "none", const char * l = "null", int r = 0);hasDMA(const char * s, const ABCDMA & rs);hasDMA(const hasDMA & hs);virtual ~hasDMA();hasDMA & operator=(const hasDMA & hs);virtual void View() const;friend std::ostream & operator<<(std::ostream & os, const hasDMA & rs);
};#endif

abcDMA.cpp

// abcDMA.cpp -- ABC DMA class methods
#include "abcDMA.h"
#include <cstring>// ABCDMA methods
ABCDMA::ABCDMA(const char * l, int r) {label = new char[strlen(l) + 1];strcpy(label, l);rating = r;
}ABCDMA::ABCDMA(const ABCDMA & rs) {label = new char[strlen(rs.label) + 1];strcpy(label, rs.label);rating = rs.rating;
}ABCDMA::~ABCDMA() {delete [] label;
}ABCDMA & ABCDMA::operator=(const ABCDMA & 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 ABCDMA & rs) {os << "Label: " << rs.label << std::endl;os << "Rating: " << rs.rating << std::endl;return os;
}// baseDMA methods
baseDMA::baseDMA(const char * l, int r) : ABCDMA(l, r) {
}baseDMA::baseDMA(const baseDMA & rs) : ABCDMA(rs) {
}baseDMA & baseDMA::operator=(const baseDMA & rs) {if (this == &rs)return *this;ABCDMA::operator=(rs);return *this;
}void baseDMA::View() const {std::cout << "baseDMA object:" << std::endl;std::cout << *this;
}std::ostream & operator<<(std::ostream & os, const baseDMA & rs) {os << (const ABCDMA &)rs;return os;
}// lacksDMA methods
lacksDMA::lacksDMA(const char * c, const char * l, int r) : ABCDMA(l, r) {strncpy(color, c, 39);color[39] = '\0';
}lacksDMA::lacksDMA(const char * c, const ABCDMA & rs) : ABCDMA(rs) {strncpy(color, c, 39);color[39] = '\0';
}void lacksDMA::View() const {std::cout << "lacksDMA object:" << std::endl;std::cout << (const ABCDMA &)(*this);std::cout << "Color: " << color << std::endl;
}std::ostream & operator<<(std::ostream & os, const lacksDMA & ls) {os << (const ABCDMA &)ls;os << "Color: " << ls.color << std::endl;return os;
}// hasDMA methods
hasDMA::hasDMA(const char * s, const char * l, int r) : ABCDMA(l, r) {style = new char[strlen(s) + 1];strcpy(style, s);
}hasDMA::hasDMA(const char * s, const ABCDMA & rs) : ABCDMA(rs) {style = new char[strlen(s) + 1];strcpy(style, s);
}hasDMA::hasDMA(const hasDMA & hs) : ABCDMA(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;ABCDMA::operator=(hs);delete [] style;style = new char[strlen(hs.style) + 1];strcpy(style, hs.style);return *this;
}void hasDMA::View() const {std::cout << "hasDMA object:" << std::endl;std::cout << (const ABCDMA &)(*this);std::cout << "Style: " << style << std::endl;
}std::ostream & operator<<(std::ostream & os, const hasDMA & hs) {os << (const ABCDMA &)hs;os << "Style: " << hs.style << std::endl;return os;
}

usedma3.cpp

// usedma3.cpp -- testing ABC DMA classes
#include <iostream>
#include <cstring>
#include "abcDMA.h"const int CLIENTS = 4;int main()
{using std::cin;using std::cout;using std::endl;ABCDMA * p_clients[CLIENTS];char temp[100];char kind;int rating;for (int i = 0; i < CLIENTS; i++){cout << "Enter label: ";cin.getline(temp, 100);cout << "Enter rating: ";cin >> rating;while (cin.get() != '\n')continue;cout << "Enter 1 for baseDMA, 2 for lacksDMA, 3 for hasDMA: ";cin >> kind;while (cin.get() != '\n')continue;switch(kind){case '1':p_clients[i] = new baseDMA(temp, rating);break;case '2':cout << "Enter color: ";cin.getline(temp, 100);p_clients[i] = new lacksDMA(temp, temp, rating);break;case '3':cout << "Enter style: ";cin.getline(temp, 100);p_clients[i] = new hasDMA(temp, temp, rating);break;default:p_clients[i] = new baseDMA(temp, rating);}}cout << endl;for (int i = 0; i < CLIENTS; i++){p_clients[i]->View();cout << endl;}for (int i = 0; i < CLIENTS; i++)delete p_clients[i];cout << "Done.\n";return 0;
}


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,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);// adds 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:20
operator<<()函数按下面的格式显示信息(末尾没有换行符):
Gallo,tawny,20
PortMaster 完成了 Port 类的方法定义后派生了 VintagePor 类,然后被解职——因为不小心将一瓶度 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 :VintaqePort(); VintagePort(const char * br, int b, const char * nn, int y);VintaqePort(const VintagePort & vp);~VintagePort() { delete [] nickname;}VintaqePort & operator=(const VintagePort & vp);void Show() const;friend ostream & operator<<(ostream & os, const VintagePort & vp);
};

您被指定负责完成 VintagePort。
a.第一个任务是重新创建 Port方法定义,因为前任被开除时销毁了方法定义。
b.第二个任务是解释为什么有的方法重新定义了,而有些没有重新定义。
c.第三个任务是解释为何没有将operator=()和 operator<<( )声明为虚的。
d.第四个任务是提供 VintagePort 中各个方法的定义。

port.h

// port.h -- Port and VintagePort classes
#ifndef PORT_H_
#define PORT_H_
#include <iostream>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); // adds b to bottlesPort & operator-=(int b); // subtracts b from bottles, if availableint BottleCount() const { return bottles; }virtual void Show() const;friend std::ostream & operator<<(std::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, int b, const char * nn, int y);VintagePort(const VintagePort & vp);~VintagePort() { delete [] nickname; }VintagePort & operator=(const VintagePort & vp);virtual void Show() const;friend std::ostream & operator<<(std::ostream & os, const VintagePort & vp);
};#endif

port.cpp

// port.cpp -- Port and VintagePort class methods
#include "port.h"
#include <cstring>// Port methods
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);strncpy(style, p.style, 19);style[19] = '\0';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);strncpy(style, p.style, 19);style[19] = '\0';bottles = p.bottles;return *this;
}Port & Port::operator+=(int b) {bottles += b;return *this;
}Port & Port::operator-=(int b) {bottles -= b;if (bottles < 0)bottles = 0;return *this;
}void Port::Show() const {std::cout << "Brand: " << brand << std::endl;std::cout << "Kind: " << style << std::endl;std::cout << "Bottles: " << bottles << std::endl;
}std::ostream & operator<<(std::ostream & os, const Port & p) {os << p.brand << ", " << p.style << ", " << p.bottles;return os;
}// VintagePort methods
VintagePort::VintagePort() : Port("none", "vintage", 0) {nickname = new char[1];nickname[0] = '\0';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();std::cout << "Nickname: " << nickname << std::endl;std::cout << "Year: " << year << std::endl;
}std::ostream & operator<<(std::ostream & os, const VintagePort & vp) {os << (const Port &)vp << ", " << vp.nickname << ", " << vp.year;return os;
}

useport.cpp

// useport.cpp -- testing Port and VintagePort classes
#include <iostream>
#include "port.h"int main()
{using std::cout;using std::endl;Port p1("Gallo", "tawny", 20);VintagePort vp1("Cockburn", 10, "Old Velvet", 1990);cout << "Port p1:" << endl;p1.Show();cout << "Port p1 (operator<<): " << p1 << endl << endl;cout << "VintagePort vp1:" << endl;vp1.Show();cout << "VintagePort vp1 (operator<<): " << vp1 << endl << endl;// Test operatorsp1 += 5;cout << "After adding 5 bottles to p1:" << endl;p1.Show();vp1 -= 3;cout << "After subtracting 3 bottles from vp1:" << endl;vp1.Show();// Test copy constructor and assignmentVintagePort vp2(vp1);cout << "Copy of vp1:" << endl;vp2.Show();VintagePort vp3;vp3 = vp1;cout << "Assigned vp1 to vp3:" << endl;vp3.Show();return 0;
}

http://www.dtcms.com/a/469976.html

相关文章:

  • 大模型前世今生(十二):Hessian矩阵
  • 蛙跳积分法:分子动力学模拟中的高效数值积分技术
  • 详解 SNMPv1 与 SNMPv2 Trap 格式
  • 书法网站建设成都微信公众号制作
  • 宜春网站制作公司wordpress图片上传慢
  • Python串口通信与MQTT物联网网关:连接STM32与物联网平台
  • MyLanViewer(局域网IP扫描软件)
  • 湛江专业建站推荐40平米小户型装修效果图
  • 147.《手写实现 Promise.all 与 Promise.race》
  • 【HarmonyOS】异步并发和多线程并发
  • 使用docker 安装dragonfly带配置文件(x86和arm)版本
  • 企业信息型网站有哪些网站建设塞西
  • 怎么看网站是什么程序做的益阳网络
  • SpringBoot通过配置类替换配置文件配置
  • 使用Customplot绘制时间-数据曲线
  • **量子算法:探索未来的发散创新之路**随着信息技术的飞速发展,量子计算作为
  • 4. 手写数字识别,推理,批处理
  • AI编程时代的文档困境与破局之道:从Cursor到完整开发体系
  • DVWA靶场之十八:API 安全(API Security)
  • ORB_SLAM2原理及代码解析:Optimizer::LocalBundleAdjustment
  • 中文wordpress站点wordpress 获取路径
  • 从零搭建 Kubernetes 1.28 高可用集群
  • 网站建设有什么岗位职责唐山广告设计制作公司
  • Apache Doris 内部数据裁剪与过滤机制的实现原理 | Deep Dive
  • 长沙百度网站建设专精特新中小企业
  • 网站上广告wordpress导出文章word
  • Voron Trident 三叉戟 组装日记
  • 南昌公司做网站网站建设湖南岚鸿建设
  • “零成本自由派”与“钉钉生态派”:斑斑与氚云的选择
  • Flutter 仿网易云音乐播放器:唱片旋转 + 歌词滚动实现记录