c/c++ 继承与多态 容器与继承1说明了容器里使用继承关系的方法,这里再弄一个练习,巩固一下。

做一个类Basket,它有个multiset成员,key是智能指针std::shared_ptr<Quote>,由于key是自定义对象,所有必须给一个比较key的函数decltype(compare)*,关于自定义key的set,参考c/c++ 标准库 set 自定义关键字类型与比较函数 。有个公有的additem成员方法,

Quote3.h

  1. #ifndef __QUOTE3_H__
  2. #define __QUOTE3_H__
  3. #include <iostream>
  4. class Quote{
  5. public:
  6. Quote() = default;
  7. Quote(const std::string& book, double pri)
  8. :bookNo(book), price(pri){}
  9. std::string isbn() const{return bookNo;}
  10. virtual double net_price(std::size_t n)const{
  11. return n * price;
  12. }
  13. virtual void debug()const{
  14. std::cout << bookNo << " " << price << std::endl;
  15. }
  16. virtual ~Quote() = default;
  17. private:
  18. std::string bookNo;
  19. protected:
  20. double price = 0.0;
  21. };
  22. class Disc_quote : public Quote{
  23. public:
  24. Disc_quote() = default;
  25. Disc_quote(const std::string& book, double price,
  26. std::size_t qyn, double disc):Quote(book, price),
  27. quantity(qyn), discount(disc){}
  28. double net_price(std::size_t) const override = 0;
  29. protected:
  30. std::size_t quantity = 0;//折扣适用的数量
  31. double discount = 0.0; //折扣率
  32. };
  33. class Bulk_quote : public Disc_quote{
  34. public:
  35. Bulk_quote() = default;
  36. Bulk_quote(const std::string& book, double price,
  37. std::size_t qyn, double disc)
  38. :Disc_quote(book, price, qyn, disc){}
  39. double net_price(std::size_t) const override;
  40. };
  41. class Min_quote : public Disc_quote{
  42. public:
  43. Min_quote() = default;
  44. Min_quote(const std::string& book, double price,
  45. std::size_t qyn, double disc)
  46. :Disc_quote(book, price, qyn, disc){}
  47. double net_price(std::size_t) const override;
  48. };
  49. #endif

Quote3.cpp

  1. #include "Quote3.h"
  2. double Bulk_quote::net_price(std::size_t cnt) const{
  3. if(cnt >= quantity){
  4. return cnt * (1 - discount) * price;
  5. }
  6. else{
  7. return cnt * price;
  8. }
  9. }
  10. double Min_quote::net_price(std::size_t cnt) const{
  11. if(cnt < quantity){
  12. return cnt * (1 - discount) * price;
  13. }
  14. else{
  15. return cnt * price;
  16. }
  17. }

Basket.h

  1. #ifndef __BASKET_H__
  2. #define __BASKET_H__
  3. #include "Quote3.h"
  4. #include <set>
  5. #include <memory>
  6. class Basket{
  7. public:
  8. void add_item(const std::shared_ptr<Quote>& sale){
  9. items.insert(sale);
  10. }
  11. double total_receipt(std::ostream&) const;
  12. private:
  13. static bool compare(const std::shared_ptr<Quote>& lhs,
  14. const std::shared_ptr<Quote>& rhs){
  15. return lhs->isbn() < rhs->isbn();
  16. }
  17. std::multiset<std::shared_ptr<Quote>, decltype(compare)*>
  18. items{compare};
  19. };
  20. #endif

Basket.cpp

  1. #include "Basket.h"
  2. double print_total(std::ostream& os,
  3. const Quote& item, size_t n);
  4. double Basket::total_receipt(std::ostream& os) const{
  5. double sum = 0.0;
  6. for(auto iter = items.cbegin();
  7. iter != items.cend();
  8. iter = items.upper_bound(*iter)){
  9. sum += print_total(os, **iter, items.count(*iter));
  10. }
  11. os << "Total Sale: " << sum << std::endl;
  12. return sum;
  13. }

main.cpp

  1. #include "Quote3.h"
  2. #include "Basket.h"
  3. #include <vector>
  4. #include <iostream>
  5. double print_total(std::ostream& os,
  6. const Quote& item, size_t n){
  7. double ret = item.net_price(n);
  8. os << "ISBN: " << item.isbn()
  9. << " # sold: " << n << " total due: " << ret << std::endl;
  10. return ret;
  11. }
  12. int main(){
  13. Basket bsk;
  14. //bsk.add_item(std::make_shared<Quote>("01", 100));
  15. bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  16. bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  17. bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  18. bsk.total_receipt(std::cout);
  19. }

执行结果1:

  1. ISBN: 01 # sold: 3 total due: 270
  2. Total Sale: 270

把main函数改成下面:

  1. int main(){
  2. Basket bsk;
  3. bsk.add_item(std::make_shared<Quote>("01", 100));
  4. //bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  5. bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  6. bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
  7. bsk.total_receipt(std::cout);
  8. }

执行结果2:

  1. ISBN: 01 # sold: 3 total due: 300
  2. Total Sale: 300

代码有点长,主要的关注点:

  • 容器里放的是智能指针
  • 第一次添加的智能指针,如果是Quote类型,执行结果就是执行结果2;如果是Bulk_quote类型,执行结果就是执行结果1;

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 继承与多态 容器与继承2的更多相关文章

  1. c/c++ 继承与多态 容器与继承3

    c/c++ 继承与多态 容器与继承2 巩固了容器里放智能指针的用法,但是有个问题,对于使用Basket类的用户来说,必须添加的是智能指针,如果能直接添加一个普通的类的对象的话,用起来就方便的多了,所以 ...

  2. c/c++ 继承与多态 容器与继承1

    问题:类B公有继承类A,类A有虚函数fun,类B覆盖了虚函数fun,有一个std::vector<A>,添加A的对象a,和B的对象b,到这个容器里,然后从vector里取出来,使用对象a. ...

  3. lua面向对象实现(实例化对象、继承、多态、多继承、单例模式)

    lua面向对象实现: 一个类就像是一个创建对象的模具.有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例.lua则没有类的概念,每个对象只能自定义行为和形态.不过,要在lua中模 ...

  4. c/c++ 继承与多态 友元与继承

    问题1:类B是类A的友元类,类C是类B的友元类,那么类C是类A的友元类吗?函数fun是类B的友元函数,那么fun是类A的友元函数吗? 都不是,友元关系不能传递. 问题2:类B是类A的友元类,类C是类B ...

  5. Java学习笔记 07 接口、继承与多态

    一.类的继承 继承的好处 >>使整个程序架构具有一定的弹性,在程序中复用一些已经定义完善的类不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性 继承的基本思想 >>基 ...

  6. Java的三大特性:封装、继承、多态

    一.类的概念: 类一般包括两个部分:属性(成员变量)和方法(成员方法)方法组成部分:修饰符(可选) 返回值类型(必须) 方法名(必须)参数列表(可选) package com.classTest.pr ...

  7. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  8. Python面向对象:继承和多态

    继承与多态简介: 继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写. 动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的. ...

  9. Java入门系列(三)面向对象三大特性之封装、继承、多态

    面向对象综述 封装 封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项,或者叫接口. 有了封装,就可以明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者:而外部调用者也可以知道 ...

随机推荐

  1. 使用jquery日期选择器flatpickr.js,使用js动态创建input元素时插件失效

    最近写页面时需要用到,日期选择器,网上搜索了一些插件,最后使用了flatpickr.js.我是从npm 上拉下的依赖  npm install flatpickr --save 随后在页面中引入css ...

  2. iOS学习——#define、const、typedef的区别

    在iOS开发中经常遇到一些字段和类型的定义,例如配置生产和测试不同环境的参数等,这时候经常用到#define.const以及typedef.那么它们之间有什么区别呢?我们接下来一个一个具体了解下. 一 ...

  3. Redux源码学习笔记

    https://github.com/reduxjs/redux 版本 4.0.0 先了解一下redux是怎么用的,此处摘抄自阮一峰老师的<Redux 入门教程> // Web 应用是一个 ...

  4. 【Android】打开本地的html文件

    网上好多说法 但实际上说到点上的没有 不想写太长 直接进入正题 Intent intent = new Intent(Intent.ACTION_VIEW); intent.addCategory(I ...

  5. [九]JavaIO之ObjectInputStream 和 ObjectOutputStream

    序列化 序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指把二进制码重新转换成Java对象的过程 序列化是一种轻量级的持久化,对象都是存活在内存中的,当JVM运行结束,对象便不存在 ...

  6. Spring基础系列--AOP织入逻辑跟踪

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9619910.html 其实在之前的源码解读里面,关于织入的部分并没有说清楚,那些前置.后 ...

  7. 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)

    一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...

  8. 用TensorFlow教你手写字识别

    博主原文链接:用TensorFlow教你做手写字识别(准确率94.09%) 如需转载,请备注出处及链接,谢谢. 2012 年,Alex Krizhevsky, Geoff Hinton, and Il ...

  9. 大前端的自动化工厂(1)——Yeoman

    一.Yeoman是什么 Yeoman是现代化前端项目的脚手架工具,用于生成包含指定框架结构的工程化目录结构.它是整个前端自动化工厂的第一站. 从个人使用者的角度来看,Yeoman的地位有些鸡肋,因为流 ...

  10. linux查看和修改PATH环境变量的方法

    查看PATH:echo $PATH以添加mongodb server为列修改方法一:export PATH=/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $PA ...