C++Primer Plus 第十四章代码重用:编程练习,第5题

C++Primer Plus 第十四章代码重用:编程练习,第5题

C++Primer Plus 第十四章代码重用:编程练习,第5题


文章目录

  • C++Primer Plus 第十四章代码重用:编程练习,第5题
  • 前言
    • 5.
  • 一、方法
  • 二、解答


前言

5.

下面是一些类声明:


//emp.h--header file for abstr emp class and children#include <iostream>
#include <string>class abstr_emp
private :
std::string fname;// abstr emp's first name//abstr emp's last name
std::string lname;
std::string job;
public:
abstr_emp();
abstr_emp(const std::string &fn,const std::string & lnconst std::string&j);
virtual void showAll()const;// labels and shows all data
virtual void SetA1l();// prompts user for values
friend std::ostream &operator<<(std::ostream &os,const abstremp&e);//just displays first and last name
virtual ~abstr_emp()=0;
//virtual base class
class employee:public abstr_emp
{
public :
employee();
employee(const std::string &fn,const std::string&ln,const std::string&j);
virtual void ShowAll()const;
virtual void SetA1l();
}class manager:virtual public abstr_emp
{
private :
int inchargeof;//number of abstr emps manaqed
protected:
int InCharge0f()const(return inchargeof;)// output
int & InChargeof()return {inchargeof};// input
public :
manager();
manager(const std::string &fn,const std::string & ln,const std::string&j,int ico=0);
manager(constabstremp&e,intico);
manager(const manager&m);
virtual void showAll()const;
virtual void SetA1l();
}class fink:virtual public abstr_emp
{
private:
//to whom fink reports
std::string reportsto;
protected:
const std::string ReportsTo()const {return reportsto};
std::string &ReportsTo() {return reportsto};
public :
fink();
fink(const std::string & fn,const std::string & ln,const std::string&j,const std::string &rpo);
fink(const abstremp &e,const std::string &rpo);
fink(const fink & e);
virtual void ShowAll()const;
virtual void SetAl1();
}
class highfink: public manager,public fink // management finkpublic:
{
highfink();
highfink(const std::string &fn,const std::string & lnconst std::string&j,const std::string&rpo,int ico);
highfink(const abstr emp &e,const std::string & rpo,int ico);
highfink(const fink & f,int ico);
highfink(const manager &m,const std::string & rpo);
highfink(const highfink & h);
virtual void ShowAll()const;
virtual void setAl1();
}

注意,该类层次结构使用了带虚基类的 M,所以要牢记这种情况下用于构造函数初始化列表的特殊规则。还需要注意的是,有些方法被声明为保护的。这可以简化一些highfnk方法的代码(例如,如果highfink::ShowAll( )只是调用 fink::ShowAll()和manager::ShwAll( ),则它将调用 abstr_emp::ShowAl( )两次)。请提供类方法的实现,并在一个程序中对这些类进行测试。下面是一个小型测试程序:

// pe14-5.cPp
// useemp1.cpp)-using the abstremp classes#include <iostream>
using namespace std;
#include "emp.h"int main(void)
{
employee em("Trip","Harris","Thumper" );
cout <<em< endl;
em.ShowAll();
manager ma("Amorphia","Spindragon""Nuancer"5);
Cout <<ma <endl;
ma .ShowAl1();
fink fi("Matt","Oggs","Oiler","Juno Barr");
cout << fi << endl;
fi.showA11();highfink hf(ma,"Curly Kew");//recruitment?
hf.showA11();
cout <<"Press a key for next phase:\n";
cin.get();
highfink hf2;
hf2.setA11();
cout <<"Using an abstr emp *pointer:\n";
abstr emp *tri[4]={&em, &fi,&hf, &hf2};
for(inti=0;i<4;i++)tri[i]->showA11();
return 0;
}
  • 为什么没有定义赋值运算符?
  • 为什么要将ShowA11()和setA11()定义为虚的?
  • 为什么要将 abstr_emp 定义为虚基类?
  • 为什么 highfink类没有数据部分?
  • 为什么只需要一个operator<<()版本?
  • 如果使用下面的代码替换程序的结尾部分,将会发生什么情况?
abstr emp tri[4]={em,fi,hf,hf2);
for(inti=0;i<4;i++)
tri[i].ShowA11();


提示:以下是本篇文章正文内容,下面案例可供参考

一、方法

#include <iostream>
#include <limits>
#include <string>using namespace std;// ========================================
class abstr_emp
{private:std::string fname;	// abstr_emp's first namestd::string lname;	// abstr_emp's last namestd::string job;public://abstr_emp();explicit abstr_emp(const std::string & fn = "", const std::string & ln = "", const std::string & j = "");virtual void ShowAll() const;	// labels and shows all datavirtual void SetAll();		// prompts user for valuesfriend std::ostream & operator<<(std::ostream & os, const abstr_emp & e);	// just displays first and last namevirtual ~abstr_emp() = 0;	// virtual base class
};abstr_emp::abstr_emp (const std::string & fn, const std::string & ln, const std::string & j): fname(fn), lname(ln), job(j)
{;
}abstr_emp::~abstr_emp ()
{;
}void
abstr_emp::ShowAll () const
{cout	<< "name: " << fname << ' ' << lname << '\n'<< "job: " << job << endl;
}void
abstr_emp::SetAll ()
{cout << "enter first name: ";cin >> fname;cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容cout << "enter second name: ";cin >> lname;cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容cout << "enter job: ";cin >> job;cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容
}std::ostream &
operator<< (std::ostream & os, const abstr_emp & e)
{e.ShowAll();return (os);
}// ========================================
class employee : public abstr_emp
{public://employee();explicit employee(const std::string & fn = "", const std::string & ln = "", const std::string & j = "");virtual void ShowAll() const;virtual void SetAll();
};employee::employee (const std::string & fn, const std::string & ln, const std::string & j): abstr_emp(fn, ln, j)
{;
}void
employee::ShowAll () const
{abstr_emp::ShowAll();
}void
employee::SetAll ()
{abstr_emp::SetAll();
}// ========================================
class manager: virtual public abstr_emp
{private:int inchargeof;	// number of abstr_emps managedprotected:int InChargeOf() const { return inchargeof; } // outputint & InChargeOf(){ return inchargeof; }	// inputpublic://manager();explicit manager(const std::string & fn = "", const std::string & ln = "", const std::string & j = "", int ico = 0);manager(const abstr_emp & e, int ico);//manager(const manager & m);virtual void ShowAll() const;virtual void SetAll();
};manager::manager (const std::string & fn, const std::string & ln, const std::string & j, int ico): abstr_emp(fn, ln, j), inchargeof(ico)
{;
}manager::manager (const abstr_emp & e, int ico): abstr_emp(e), inchargeof(ico)
{;
}void
manager::ShowAll () const
{abstr_emp::ShowAll();cout << "incharge of " << inchargeof << " employees" << endl;
}void
manager::SetAll ()
{abstr_emp::SetAll();cout << "enter the number of managed: ";cin >> inchargeof;cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容
}// ========================================
class fink: virtual public abstr_emp
{private:std::string reportsto;	// to whom fink reportsprotected:const std::string ReportsTo() const { return reportsto; }std::string & ReportsTo(){ return reportsto; }public://fink();fink(const std::string & fn = "", const std::string & ln = "", const std::string & j = "", const std::string & rpo = "");fink(const abstr_emp & e, const std::string & rpo);//fink(const fink & e);virtual void ShowAll() const;virtual void SetAll();
};fink::fink (const std::string & fn, const std::string & ln, const std::string & j, const std::string & rpo): abstr_emp(fn, ln, j), reportsto(rpo)
{;
}fink::fink (const abstr_emp & e, const std::string & rpo): abstr_emp(e), reportsto(rpo)
{;
}void
fink::ShowAll () const
{abstr_emp::ShowAll();cout << "report to " << reportsto << endl;
}void
fink::SetAll ()
{abstr_emp::SetAll();cout << "enter to whom fink reports: ";cin >> reportsto;cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容
}// ========================================
class highfink: public manager, public fink // management fink
{public://highfink();explicit highfink(const std::string & fn = "", const std::string & ln = "", const std::string & j = "", const std::string & rpo = "", int ico = 0);//highfink(const abstr_emp & e, const std::string & rpo, int ico);highfink(const fink & f, int ico);highfink(const manager & m, const std::string & rpo);//highfink(const highfink & h);virtual void ShowAll() const;virtual void SetAll();
};highfink::highfink (const std::string & fn, const std::string & ln, const std::string & j, const std::string & rpo, int ico): abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rpo)
{;
}highfink::highfink(const fink & f, int ico): abstr_emp(f), manager(f, ico), fink(f)
{;
}highfink::highfink (const manager & m, const std::string & rpo): abstr_emp(m), manager(m), fink(m, rpo)
{;
}void
highfink::ShowAll() const
{manager::ShowAll();cout << "report to " << ReportsTo() << endl;
}void
highfink::SetAll()
{manager::SetAll();cout << "enter to whom fink reports: ";cin >> ReportsTo();cin.clear();	// 清空输入缓冲区错误标志位cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');	// 清空输入缓冲区内容
}// ========================================
int main(void)
{employee em("Trip", "Harris", "Thumper");cout << em << endl;//em.ShowAll();manager ma("Amorphia", "Spindragon", "Nuancer", 5);cout << ma << endl;//ma.ShowAll();fink fi("Matt", "Oggs", "Oiler", "Juno Barr");cout << fi << endl;//fi.ShowAll();highfink hf(ma, "Curly Kew"); // recruitment?cout << hf << endl;//hf.ShowAll();cout << endl;cout << "Press a key for next phase:\n";cin.get();highfink hf2;hf2.SetAll();cout << endl;cout << "Using an abstr_emp * pointer:\n";abstr_emp * tri[4] = {&em, &fi, &hf, &hf2};for (int i = 0; i < 4; i++)tri[i]->ShowAll();return 0;
}

二、解答

Why is no assignment operator defined?
——abstr_emp、employee、manager、fink、highfink 等五个类内部并未涉及动态内存分配,并非深拷贝,因此,无须定义赋值运算符、拷贝构造函数、析构函数。

Why are ShowAll() and SetAll() virtual?
为什么要将 ShowAll() 和 SetAll() 定义为虚的?
——各级派生类均有各自新增的数据成员,显示、设置新增数据成员必须由派生类自行负责,无法直接复用基类的 ShowAll() 和 SetAll() 成员函数,在这两类操作上,派生类需要体现出类的多态特性。

Why is abstr_emp a virtual base class?
——若 abstr_emp 按一般方式派生出 manager、fink,而 manager、fink 派生出 highfink,highfink 将包含两份 abstr_emp 的数据成员,必须将 abstr_emp 通过 virtual 方式派生出 manager、fink,才能正常地只包含一份 abstr_emp 的数据成员。

Why does the highfink class have no data section?
——highfink 通过 manager、fink 多重继承而来,无须新增数据成员。

Why is only one version of operator<<() needed?
——friend std::ostream & operator<<(std::ostream & os, const abstr_emp & e) 的形参是基类引用,各派生类实现了各自的 virtual ShowAll() 函数,因此,operator<<() 在内部通过多态特性调用基类和派生类各自的 ShowAll() 实现输出。但是,书上的原型声明 virtual void ShowAll() const 有误,应改为 virtual std::ostream& ShowAll(std::ostream& os) const;

What would happen if the end of the program were replaced with this code?
abstr_emp tri[4] = {em, fi, hf, hf2};
for (int i = 0; i < 4; i++)
tri[i].ShowAll();
——语法错误,由于 abstr_emp 中含有纯虚成员函数,所以 abstr_emp 为抽象类,抽象类无法创建对象。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenSSL EVP详解

OpenSSL EVP详解 Chapter1 OpenSSL EVP详解一、EVP基本介绍1. EVP 加密和解密2. EVP 签名和验证3. EVP 加解密文件 二、源码结构2.1 全局函数2.2 BIO扩充2.3 摘要算法EVP封装2.4 对称算法EVP封装2.5 非对称算法EVP封装2.6 基于口令的加密 三、开发实例3.1 示例13.2 示例23.3 示…

【MySQL】数据库——备份与恢复,日志管理

一、数据备份的重要性 1.备份的主要目的是灾难恢复 在生产环境中&#xff0c;数据的安全性至关重要 任何数据的丢失都可能产生严重的后果造成数据丢失的原因&#xff1a; 程序错误人为,操作错误运算错误磁盘故障灾难&#xff08;如火灾、地震&#xff09;和盗窃 2.数据库备份…

【5G射频基本架构】

平台框架 平台演进及搭配 5G NR频谱 NSA/SA/ENDC 在双连接中&#xff0c;UE在连接状态下可同时使用至少两个不同基站的无线资源。对于Sprint&#xff0c;ENDC将允许设备在相同的频段&#xff08;41 / 2.5 GHz频段&#xff09;上同时访问LTE和5G。 手机硬件实现ENDC方式—类似LT…

动态住宅代理IP的优势是什么?什么地方用到?

在大数据时代的背景下&#xff0c;代理IP成为了很多企业顺利开展的重要工具。代理IP地址可以分为住宅代理IP地址和数据中心代理IP地址。选择住宅代理IP的好处是可以实现真正的高匿名性&#xff0c;而使用数据中心代理IP可能会暴露自己使用代理的情况。 住宅代理IP是指互联网服务…

数据库系统概论 | 触发器代码 | 行级触发器 | 语句级触发器

触发器 这篇博客拿两个例子来解释一下什么是行级触发器和语句级触发器。 **例子1&#xff1a;**当对表SC的Grade属性进行修改时&#xff0c;若分数增加了10%&#xff0c;则将此次操作记录到另一个表SC_U&#xff08;Sno CHAR(8)、Cno CHAR(5)、Oldgrade SMALLINT、Newgrade S…

Flink 窗口触发器(Trigger)(一)

Flink 窗口触发器(Trigger)(一) Flink 窗口触发器(Trigger)(二) Flink的窗口触发器&#xff08;Trigger&#xff09;是流处理中一个非常关键的概念&#xff0c;它定义了窗口何时被触发并决定触发后的行为&#xff08;如进行窗口数据的计算或清理&#xff09;。 一、基本概念 …

[数据集][目标检测]人员状态跑睡抽烟打电话跌倒检测数据集4943张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4943 标注数量(xml文件个数)&#xff1a;4943 标注数量(txt文件个数)&#xff1a;4943 标注…

[Leetcode 136][Easy]-只出现一次的数字

目录 题目描述 具体思路 题目描述 原题链接 具体思路 ①首先看到数组中重复的数字&#xff0c;想到快慢指针&#xff0c;但是数组的元素是乱序的不好求。因此先对数组排序。使用了STL库的sort函数&#xff0c;时间复杂度O(nlogn)不符合题目要求&#xff0c;空间复杂度O(1)。…

Pytorch学习之torch.split函数

Pytorch学习之torch.split函数 一、简介 torch.split用于将一个张量&#xff08;tensor&#xff09;沿指定维度&#xff08;dim&#xff09;拆分为多个子张量。这个函数对于处理需要按块拆分数据的任务非常有用&#xff0c;例如在自然语言处理和图像处理中的数据预处理。 二…

RXMH2 RK223 069 AS大容量中间继电器 板前接线 约瑟JOSEF

RXMH2大容量中间继电器型号&#xff1a; RXMH2 RK 223 067大容量中间继电器&#xff1b; RXMH2 RK 223 068大容量中间继电器&#xff1b; RXMH2 RK 223 069大容量中间继电器&#xff1b; RXMH2 RK 223 070大容量中间继电器&#xff1b; 用途 用于电力系统二次回路及工业自…

基于Hadoop平台的电信客服数据的处理与分析③项目开发:搭建Kafka大数据运算环境---任务11:基础环境准备

任务描述 任务主要是安装配置基础环境&#xff0c;主要内容包括&#xff1a; 1、安装java Kafka和ZooKeeper都需要安装Java环境&#xff0c;推荐至少Java8及以上版本 2、安装ZooKeeper ZooKeeper是Kafka集群的必要组件 3、安装kafka Kafka版本包括使用的scala语言版本和kafka版…

Ubuntu22.04上Docker的安装

1. 使用APT安装 首先安装HTTPS传输的软件包和CA证书&#xff0c;确保软件下载过程中不被篡改。 sudo apt-get updatesudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y然后&#xff0c;使用国内源&#xff0c;并添加软件源的 GPG 密钥以防…

Java面试题:讨论持续集成/持续部署的重要性,并描述如何在项目中实施CI/CD流程

持续集成/持续部署&#xff08;CI/CD&#xff09;的重要性 持续集成&#xff08;Continuous Integration, CI&#xff09; 和 持续部署&#xff08;Continuous Deployment, CD&#xff09; 是现代软件开发的重要实践。这些方法通过自动化构建、测试和部署过程&#xff0c;显著…

Ubuntu 用户配置

环境信息 系统版本Ubuntu16.04.1-Ubuntu x86_64 创建用户组 新建一个用户组&#xff0c;GID为888。 sudo addgroup –g 888 组名删除用户组 sudo delgroup 组名创建用户 username 为用户名&#xff0c;执行后系统会提示输入新用户的密码&#xff0c;后续输入其他信息&#xff0…

代码随想录day34 贪心(5)

56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 写法一&#xff1a;维护right和left两个数作为当前区间的左右边界 class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:intervals.sort(key lambda x: x[0])left intervals[0][0]ri…

番外1:企业数据

数据类别说明 企业中除了主数据和次级数据外,企业中还有其他一些常见的数据分类,这些数据类型根据其特定的用途和性质,在企业的各个功能和部门中起着重要作用。 主数据(Master Data) 主数据是企业中核心、长期存在且在整个组织中广泛使用的关键数据。主数据具有以下特征:…

Vue2和Vue3的区别Vue3的组合式API

一、Vue2和Vue3的区别 1、创建方式的不同&#xff1a; &#xff08;1&#xff09;、vue2:是一个构造函数&#xff0c;通过该构造函数创建一个Vue实例 new Vue({})&#xff08;2&#xff09;、Vue3:是一个对象。并通过该对象的createApp()方法&#xff0c;创建一个vue实例。 Vue…

RAG技术下的文档智能检索

在数字化浪潮的推动下&#xff0c;信息检索已成为我们日常生活中不可或缺的一部分。然而&#xff0c;随着数据量的爆炸式增长&#xff0c;如何快速精准地从海量文档中检索出有价值的信息&#xff0c;成为了一个巨大的挑战。本文将带您走进 Pinecone 向量数据库的世界&#xff0…

AIGC到底如何改变创意设计?

在当今数字化时代&#xff0c;AIGC&#xff08;生成式人工智能&#xff09;技术的崛起对创意设计领域产生了深远的影响。AIGC不仅为设计师提供了新的工具和方法&#xff0c;还改变了传统的设计流程和思维方式。 传统的设计过程中&#xff0c;设计师需要耗费大量时间在绘图、修…

npm install puppeteer 报错 npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated解决办法

npm install puppeteer 报错如下&#xff1a; npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL instead. npm ERR! Error: ERROR: Failed to set up Chrome v126.0.6478.126! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to sk…