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.pswp.cn/diannao/39926.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39926.shtml
英文地址,請注明出處:http://en.pswp.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…