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 name
		std::string lname;	// abstr_emp's last name
		std::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 data
		virtual void SetAll();		// prompts user for values
		friend std::ostream & operator<<(std::ostream & os, const abstr_emp & e);	// just displays first and last name
		virtual ~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 managed

	protected:
		int InChargeOf() const { return inchargeof; } // output
		int & InChargeOf(){ return inchargeof; }	// input

	public:
		//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 reports
	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 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.mfbz.cn/a/768459.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一场别开生面的python应用实战案例

学好python&#xff0c;改变人生&#xff01; 最近看了央视旗下的玉渊潭天微博介绍了菲律宾control我们sina微博的视频&#xff0c;这是一个难得的python实战案例&#xff0c;至少有四五个python重要硬核方向值得研究&#xff0c;所以今天写一下这个相关的一些技术领域&#xf…

Redis持久化的三种方式(RDB、AOF和混合)

Redis持久化的三种方式(RDB、AOF和混合) 目录 Redis持久化的三种方式(RDB、AOF和混合)介绍RDB示例1.配置文件2.触发 RDB 快照保存3.验证 AOF示例1.配置文件2.校验 混合型持久化存储配置文件 介绍 Redis数据主要存储与内存中&#xff0c;因此如果服务器意外重启、宕机、崩溃&am…

elementui中@click短时间内多次触发,@click重复点击,做不允许重复点击处理

click快速点击&#xff0c;发生多次触发 2.代码示例&#xff1a; //html<el-button :loading"submitLoading" type"primary" click"submitForm">确 定</el-button>data() {return {submitLoading:false,}}//方法/** 提交按钮 */sub…

页面替换菜单栏图标

图标素材库&#xff1a;https://www.iconfont.cn/?spma313x.collections_index.i3.2.51703a81hOhc8B 1、找到自己喜欢的图标下载svg 2、添加到icons中 3、在components中创建对应的vue页面添加对应图标svg中代码 4、在router中引入 5、在对应的菜单下使用图标

复旦大学:一个小技巧探测大模型的知识边界,有效消除幻觉

孔子说“知之为知之&#xff0c;不知为不知&#xff0c;是知也”&#xff0c;目前的大模型非常缺乏这个能力。虽然大模型拥有丰富的知识&#xff0c;但它仍然缺乏对自己知识储备的正确判断。近年来LLMs虽然展现了强大的能力&#xff0c;但它们偶尔产生的内容捏造&#xff0c;即…

基于改进YOLOv5s的跌倒行为检测 | 引入SKAttention注意机制 + 引入空间金字塔池化结构SPPFCSPC + 结合ASFF自适应空间融合

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。为了实现电厂人员跌倒行为的实时检测&#xff0c;防止跌倒昏迷而无法及时发现并救援的事件发生&#xff0c;针对跌倒行为检测实时性以及特征提取能力不足的问题&#xff0c;提出了一种改进YOLOv5s的跌倒行为检测算法网络&a…

MySQL期末答辩—仓库管理系统

仓库管理系统&#xff1a;仓库管理系统是一种基于互联网对实际仓库的管理平台&#xff0c;旨在提供一个方便、快捷、安全的存取货物和查询商品信息平台。该系统通过在线用户登录查询&#xff0c;可以线上操作线下具体出/入库操作、查询仓库商品信息、提高仓库运作效率&#xff…

一文包学会ElasticSearch的大部分应用场合

ElasticSearch 官网下载地址&#xff1a;Download Elasticsearch | Elastic 历史版本下载地址1&#xff1a;Index of elasticsearch-local/7.6.1 历史版本下载地址2&#xff1a;Past Releases of Elastic Stack Software | Elastic ElasticSearch的安装(windows) 安装前所…

1000T的文件怎么能快速从南京传到北京?最佳方案你肯定想不到

今天刷面试题看到一个有意思的面试题&#xff0c; 1000T的文件怎么能以最快速度从南京传到北京&#xff1f; 网络传输 首先我们考虑通过网络传输&#xff0c;需要多长时间。 我特地咨询了在运营商工作的同学&#xff0c;目前带宽&#xff1a; 家庭宽带下行最大1Gbps&#…

双指针系列第 8 篇:盛水最多的容器。几句话讲明白!

Leetcode 题目链接 思路 取首尾双指针和水量如下所示&#xff0c;设高度函数为 h ( i ) h(i) h(i)&#xff0c;在下图中 h ( l ) < h ( r ) h(l) < h(r) h(l)<h(r)。 观察以 l l l 为左边界所能构成的其他水量&#xff0c;与矮的右边界搭配结果如下。 与高的…

每日两题 / 20. 有效的括号 155. 最小栈(LeetCode热题100)

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 遇到左括号入栈 遇到右括号判断栈顶是否为匹配的左括号 最后判断栈是否为空 func isValid(s string) bool {var stk []runefor _, value : range s {if value ( || value { || value [ {stk append(stk, value)}…

计算机操作系统部分选填及大题整理

并发和&#xff08; 共享 &#xff09; 是操作系统的两个最基本的特征,&#xff08; 虚拟 &#xff09;和&#xff08; 异步 &#xff09; 是操作系统的重要特征&#xff0c;并发执行的程序失去可再现性现代操作系统的两个基本特征是&#xff08;程序的并发执行&#xff09;和资…

Docker 部署 Minio 对象存储服务器

文章目录 Github官网文档简介dockerdocker-compose.ymlmc 客户端mc 基础命令Golang 示例创建 test 账号密钥文件上传示例 Github https://github.com/minio/minio 官网 https://min.io/https://www.minio.org.cn/ 文档 https://www.minio.org.cn/docs/minio/kubernetes/up…

1.4 ROS2集成开发环境搭建

1.4.1 安装VSCode VSCode全称Visual Studio Code&#xff0c;是微软推出的一款轻量级代码编辑器&#xff0c;免费、开源而且功能强大。它支持几乎所有主流的程序语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比Diff、GIT 等特性&#xff0c;支持插件…

上位机第二弹

之前写的代码用上了 现在想想 &#xff0c;北向一侧还挺难搞&#xff0c;设计很巧妙

10 Posix API与网络协议栈

POSIX概念 POSIX是由IEEE指定的一系列标准,用于澄清和统一Unix-y操作系统提供的应用程序编程接口(以及辅助问题,如命令行shell实用程序),当您编写程序以依赖POSIX标准时,您可以非常肯定能够轻松地将它们移植到大量的Unix衍生产品系列中(包括Linux,但不限于此!)。 如…

使用pyinstaller 如何打包python项目

参考&#xff1a;【python项目正确打包方法-哔哩哔哩】 https://b23.tv/EDB6zbG Pyinstaller 详解多种打包过程(去坑,填坑)。_pyinstaller -f -w-CSDN博客 1.打开命令提示符&#xff1a; 找到python项目所在位置&#xff0c;输入cmd即可 2. 安装pipenv: 在命令提示符&#…

【Linux】多线程(一万六千字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 线程的概念 线程的理解(Linux系统为例) 在Linux系统里如何保证让正文部分的代码可以并发的去跑呢&#xff1f; 为什么要有多进程呢&#xff1f; 为…

CVD-Risk-Prevent 个性化心血管健康推荐系统:基于医学指南的规则框架与 LLM 的结合

CVD-Risk-Prevent 个性化心血管健康推荐系统&#xff1a;基于医学指南的规则框架与 LLM 的结合 提出背景推荐算法的选择选择疑问健康指标管理心血管风险因素目标设定实现目标的计划推荐的多维性 算法关键点&#xff1a;如何将心血管健康指标转换为多维推荐&#xff1f;确定风险…

antfu/ni 在 Windows 下的安装

问题 全局安装 ni 之后&#xff0c;第一次使用会有这个问题 解决 在 powershell 中输入 Remove-Item Alias:ni -Force -ErrorAction Ignore之后再次运行 ni Windows 11 下的 Powershell 环境配置 可以参考 https://github.com/antfu-collective/ni?tabreadme-ov-file#how …