//19 利用私有继承来实现代码重用
//我们还有一种方法来实现这种包含式的代码重用,那就是私有继承,派生类从基类私有继承后,其类的公有成员和保护成员在派生类中都是私有成员,私有成员成为不可访问的成员,这意味着我们必须在派生类中定义一个公有的成员函数,才能访问从基类中继承而来的成员函数,这与一个类的私有区域中包含另一个类的对像是实现思想是一致的
/*
#include <iostream>
#include <limits>
using namespace std;
class Date
{
public:Date(int n, float p):number(n),price(p){}float GetPrice()const{ return price; }int GetNumber()const{ return number;}virtual void print()const = 0; //抽像类,纯虚函数virtual ~Date(){}
private:int number;  //编号float price; //介格
};class Book:public Date
{
public:Book(int n, float p):Date(n,p){}virtual void print()const //定义纯虚函数{cout<<"图书的编号为:"<<GetNumber()<<endl;cout<<"图书的价格为:"<<GetPrice()<<endl;}
private:
};class Drug:public Date
{
public:Drug(int n, float p):Date(n,p){}virtual void print()const //定义纯虚函数{cout<<"药品的编号为:"<<GetNumber()<<endl;cout<<"药品的价格为:"<<GetPrice()<<endl;}
private:
};//节点类
class Node
{
public:Node(Date*pDate):itsDate(pDate),itsNext(0){}~Node(){ delete itsDate; itsDate=0;}void SetNext(Node*node){ itsNext = node; }  //设置下个节点//获取下个节点的地址Node *GetNext()const{ return itsNext; }//获取当前地址对像的地址Date *GetDate()const{ if(itsDate){return itsDate;}else{return NULL;}}
private:Date*itsDate; //当前数据Node*itsNext; //下一个节点
};//list链表类
class List
{
public:List():head(0),count(0){}~List(); //删除所有节点Date *GetFirst()const;Date *operator[](int)const; //重载下标运算符void show()const; //输出所有节点数int GetCount()const{ return count;} //取得节点数目void InSert(Date*);//插入节点void Delete(int number); //节点编号指的是商品的编号Date*Find(int number)const; //查找数据Date*Find(int &increase, int number)const; //查找数据private:Node*head; //头节点int count; //节点数目
};List::~List()
{Node*l=head;Node*m=0; //int n=0;while(l){m=l;l = l->GetNext();delete m;n++;cout<<"删除第"<<n<<"个节点!"<<endl;}
}
//获取头节点数据对像的地址
Date *List::GetFirst()const
{if(head){return head->GetDate();}else{return NULL;}
}Date *List::operator[](int offset)const
{Node* pn = head;if(!head){return NULL;}//注这里的要把下标在一个安全的范围内if(offset>=count){ //元素值大于总数return NULL;}for(int i=0; i<offset; i++){pn = pn->GetNext();}return pn->GetDate();
}void List::show()const
{if(!head){return;}Node *pn = head;do{pn->GetDate()->print();}while(pn = pn->GetNext());
}void List::InSert(Date *pDate)
{Node *pn =    new Node(pDate);Node *pNow = head;Node *pNext = 0;  //当前节点的下一个节点的地址,实始化为0int New=pDate->GetNumber(); //取得商品编号int next = 0; //下一个节点的商品编号count++;if(!head){ //设置头节点,判断头节点是否存在head = pn;return;}//头节点的数据的number值是否大于新节点的编号if(head->GetDate()->GetNumber() > New){ //将新节点设置为头节点,头节点成为了新节点的下一个节点pn->SetNext(head); //将新节点的下一个节点设置为头节点head = pn;         //将来pn设置的新节点设置为新节点return;}for(;;){//当前节点的next指针是否为空,也就是有没有下一个指针对if(!pNow->GetNext()){pNow->SetNext(pn); //将新节点设置为下一个节点return;}pNext = pNow->GetNext(); //当前节点还有下一个节点,那么获取当前节点的下一个节点next = pNext->GetDate()->GetNumber(); //取得下一个节点的number值if(next > New){ //当前节点的下一个节点的编号,与新节点的编号相对比pNow->SetNext(pn);//当前节点的下一个节点设置为新节点pn->SetNext(pNext); //用pn指向的下一个节点的设置为当前节点的下一个节点return;}pNow = pNext; //如果没有找到相应的位置,那么将当前节点的下一个节点设置为当前节点}
}
//删除函数
void List::Delete(int number)
{Node *pBack=head; //保存上一个节点的地址,初始化的地址为头节点的地址Node *pNow=head;  //当前节点,初始化为头节点的地址if(!head){cout<<"没有数据可删除!"<<endl;return;}//如果是删除的是头节点if(head->GetDate()->GetNumber() == number){//判断头节点下面是否还有节点if(!head->GetNext()){ //不存在下一个节点delete head;cout<<"数据被清空!"<<endl;head=0;count--; //数目减一return;}else{ //如果头节点有子节点head = head->GetNext();delete pNow;pNow =0;cout<<"删除成功!"<<endl;count--;return;}}while(pBack){if(pBack->GetNext() == NULL){ //没有下一个节点cout<<"找不到要删除的编号"<<endl;return;}if(pBack->GetNext()->GetDate()->GetNumber() == number){pNow = pBack->GetNext();pBack->SetNext(pNow->GetNext()); //头节点和被删除节点的下一个节点相联起来delete pNow;cout<<"删除数据成功!"<<endl;pNow = 0;count--;return;}pBack = pBack->GetNext();     }cout<<"不存在此编号数据"<<endl;
};//查找节点
Date* List::Find(int number)const
{Node* pn = 0; //来保存每个节点的地址//cout<<"List::Find:"<<endl;for(pn=head; pn!=NULL; pn=pn->GetNext()){//cout<<"pn->GetDate()->GetNumber():"<<pn->GetDate()->GetNumber()<<"="<<number<<endl;if(pn->GetDate()->GetNumber() == number){           break;}}if(pn==NULL){return NULL;}else{return pn->GetDate();}return NULL;
}Date*List::Find(int &increase, int number)const
{Node*pn=0;//cout<<"List::Find"<<endl;for(pn=head, increase=0;  pn!=NULL; pn=pn->GetNext(), increase++){if(pn->GetDate()->GetNumber() == number){break;}     }if(pn == NULL){return NULL;}else{return pn->GetDate();}return NULL;
}class Repair : private List
{
public:void RInsert(Date*newdate);void Ran();
private://List pl;
};void Repair::Ran()
{//List pl;Date *pDate =0;int number; //编号float price; //价格int choice;  //选项bool quit=false; while(1){system("cls");cout<<"(1)添加商口 (2)列出所有商品 (3)删除商品 (4)查找商品 (5)统计商品数目 (6)退出"<<endl;cin>>choice;switch(choice){case 1: //添加商品while(1){cout<<"(0)返回 (1)图书 (2)药品"<<endl;cin>>choice;if(!choice){break;}else if(choice==1 || choice==2){cout<<"请输入编号"<<endl;cin>>number;if(choice==1){cout<<"请输入图书价格"<<endl;cin>>price;pDate = new Book(number,price);//pl.InSert(pDate);RInsert(pDate);}else if(choice==2) {                  cout<<"请输入药品价格"<<endl;cin>>price;pDate = new Drug(number,price);//pl.InSert(pDate);RInsert(pDate);}else{cout<<"请输入0到2之间的数字"<<endl;}}}break;case 2: //例出所有商品if(GetFirst()==0){cout<<"您的商品为空,请增加商品"<<endl;cout<<"按回车键返回主窗口"<<endl;cin.get();cin.get();}else{show(); cout<<"请按回车链返回主窗口"<<endl;cin.get();cin.get();}break;case 3: //删除商品cout<<"请输入你要删除的商品编号:"<<endl;cin>>number;Delete(number);cin.get();cin.get();break;case 4: //查找商品while(1){cout<<"(0)返回 (1)按编号进行查询 (2)按序号进行查询"<<endl;cin>>choice;if(!choice){break;}else if(choice==1 || choice==2){if(choice==1){cout<<"请输入所有查找的商品编号"<<endl;cin>>number;Date*result = Find(number);if(result==0){cout<<"找不到该编号"<<endl;}else{result->print();//print是虚函数,可以去动态}                     }else if(choice==2) {    cout<<"请输入所要查找的数据的序号:"<<endl;cin>>number;if((*this)[number-1]){(*this)[number-1]->print();}else{cout<<"找不到你要查询的数据"<<endl;}}else{cout<<"请输入0到2之间的数字"<<endl;}}}break;case 5: //统计代码cout<<"该链表共有"<<GetCount()<<"节点"<<endl;cin.get();cin.get();break;case 6://退出quit = true;break;default:cin.clear(); //用来清除cin的错误状态//清空输入缓冲区中 numeric_limits<streamsize>::max()返回缓冲区的大小cin.ignore(numeric_limits<streamsize>::max(),'\n');cout<<"您只可以输入1-6之间的数字,请重新输入"<<endl;cout<<"请按回输键返回并重新输入"<<endl;cin.get();cin.get();break;}if(quit){cout<<"程序结束"<<endl;break;} }
}void Repair::RInsert(Date*newdate)
{int num = newdate->GetNumber();int place =0; //查找数据的次数cout<<"num:"<<num<<endl;if(Find(place,num)){cout<<"您输入的编号"<<num<<"与链表中"<<endl;cout<<"第"<<place+1<<"的编号重复"<<endl;}else{InSert(newdate);}
}int main()
{Repair rp;rp.Ran();return 0;
}
*/

  

第十九章 19 利用私有继承来实现代码重用相关推荐

  1. C++_Primer_学习笔记_第十九章(特殊工具和技术)

    第十九章(特殊工具与技术) /1.控制内存分配 1).不能直接应用标准内存管理机制. 某一些应用程序需要自定义内存分配的的细节,比如使用关键字new将对象放置在特定的内存空间中. 为了实现这一个目的, ...

  2. C++Primer5th 第十九章 特殊工具与技术

    第十九章 特殊工具与技术 19.1 控制内存分配 19.1.1 重载new和delete malloc函数与free函数 19.1.2 定位new表达式 19.2 运行时类型识别 19.2.1 dyn ...

  3. 鸟哥的Linux私房菜(服务器)- 第十九章、主机名控制者: DNS 服务器

    第十九章.主机名控制者: DNS 服务器 最近更新日期:2011/08/05 我们都知道,在『记忆』的角色上,人脑总是不如计算机的,而人们对文字的印象又比数字高.因此,想要使用纯粹的 TCP/IP 来 ...

  4. 第十九章、主機名稱控制者: DNS 伺服器

    转自:http://linux.vbird.org/linux_server/0350dns.php 第十九章.主機名稱控制者: DNS 伺服器 最近更新日期:2011/08/05 我們都知道,在『記 ...

  5. 【正点原子FPGA连载】第十九章FreeRtos Hello World实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

    1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...

  6. 《C++Primer》第十九章

    第十九章 特殊工具与技术 控制内存分配 1. 重载new和delete 重载这两个运算符与重载其他运算符的过程大不相同.想要真正重载new和delete的方法,首先要对new表达式和delete表达式 ...

  7. bmp文件头_「正点原子FPGA连载」第十九章SD卡读BMP图片LCD显示

    1)摘自[正点原子]领航者 ZYNQ 之嵌入式开发指南 2)实验平台:正点原子领航者ZYNQ开发板 3)平台购买地址:https://item.taobao.com/item.htm?&id= ...

  8. 鸟哥的Linux私房菜(基础篇)- 第十九章、认识与分析登录文件

    第十九章.认识与分析登录文件 最近升级日期:2009/09/14 当你的 Linux 系统出现不明原因的问题时,很多人都告诉你,你要查阅一下登录文件才能够知道系统出了什么问题了,所以说,了解登录文件是 ...

  9. stm32l0的停止模式怎么唤醒_「正点原子STM32Mini板资料连载」第十九章 待机唤醒实验...

    1)实验平台:正点原子STM32mini开发板 2)摘自<正点原子STM32 不完全手册(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第十九章 待机唤醒实验 本章我们将向 ...

最新文章

  1. python psutil库安装_安装psutil模块报错安装python-devel
  2. 【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)
  3. 【Python 标准库学习】伪随机数生成库 — random
  4. 一个人的战斗---走出软件作坊:三五个人十来条枪 如何成为开发正规军(十九)[转]...
  5. 【特色团队采访】慌呀哩团队,用简洁算法达成高效协作
  6. android:id=@android:id/tabhost 、android:id=@+id/llRoot 、android:id=@id/llRoot 之间的区别...
  7. 代码视角深入浅出理解 DevOps | 原力计划
  8. 如何判断一个女孩是不是真的爱你?
  9. C++中long是什么类型
  10. Spring核心注解
  11. 常用数据库分页查询SQL汇总
  12. P值计算(Excel)
  13. 计算机开机显示器无显示器,电脑开机显示器显示无信号怎么办
  14. 博士申请 | 香港大学黄凯斌教授招收6G通信与机器学习方向全奖博士生
  15. esxi怎么传输文件到虚拟机_软路由篇2:3865U软路由折腾记——Esxi软虚拟机+OpenWrt教程
  16. 一个9年运维的经验之路
  17. 机械革命无法使用U盘启动linux,机械革命如何用u盘装系统
  18. 互联网上要创业 选好域名很重要
  19. Linux技术(1)--CentOS 6.5关闭防火墙步骤
  20. 创建目录 mkdir

热门文章

  1. Resharper 检测所有NullReferenceExceptions(空指针)
  2. 用通配符解决mappingResources的繁琐配置
  3. SafeNet宣布推出其最小的圣天诺HASP硬件型软件保护锁
  4. c# BackgroundWorker组件介绍(属性、方法、事件)
  5. 如何让SiteMapPath使用指定路径指定名称的sitemap文件。
  6. 跳车开发者Pokkst自述——从BTC到BCH
  7. 锚定比特币现金(BCH),助力构建价值互联网时代
  8. BCH:“变法”是以史为鉴
  9. 【VBA】点击工作簿中的每个单元格,整行整列变色
  10. intellij haskell 插件使用分享