zoukankan      html  css  js  c++  java
  • c/c++ 继承与多态 容器与继承2

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

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

    Quote3.h

    #ifndef __QUOTE3_H__
    #define __QUOTE3_H__
    
    #include <iostream>
    
    class Quote{
     public:
      Quote() = default;
      Quote(const std::string& book, double pri)
        :bookNo(book), price(pri){}
      std::string isbn() const{return bookNo;}
      virtual double net_price(std::size_t n)const{
        return n * price;
      }
      virtual void debug()const{
        std::cout << bookNo << " " << price << std::endl;
      }
      virtual ~Quote() = default;
     private:
      std::string bookNo;
     protected:
      double price = 0.0;
    };
    
    class Disc_quote : public Quote{
     public:
      Disc_quote() = default;
      Disc_quote(const std::string& book, double price,
    	     std::size_t qyn, double disc):Quote(book, price),
        quantity(qyn), discount(disc){}
      
      double net_price(std::size_t) const override = 0;
     protected:
      std::size_t quantity = 0;//折扣适用的数量
      double discount = 0.0;   //折扣率
    };
    
    class Bulk_quote : public Disc_quote{
     public:
      
      Bulk_quote() = default;
      
      Bulk_quote(const std::string& book, double price,
      std::size_t qyn, double disc)
      :Disc_quote(book, price, qyn, disc){}
      
      double net_price(std::size_t) const override;
    };
    
    class Min_quote : public Disc_quote{
     public:
      
      Min_quote() = default;
      Min_quote(const std::string& book, double price,
      	   std::size_t qyn, double disc)
       :Disc_quote(book, price, qyn, disc){}
      
      double net_price(std::size_t) const override;
    };
    
    #endif
    
    

    Quote3.cpp

    #include "Quote3.h"
    
    double Bulk_quote::net_price(std::size_t cnt) const{
      if(cnt >= quantity){
        return cnt * (1 - discount) * price;
      }
      else{
        return cnt * price;
      }
    }
    
    
    double Min_quote::net_price(std::size_t cnt) const{
      if(cnt < quantity){
        return cnt * (1 - discount) * price;
      }
      else{
        return cnt * price;
      }
    }
    
    
    

    Basket.h

    #ifndef __BASKET_H__
    #define __BASKET_H__
    #include "Quote3.h"
    #include <set>
    #include <memory>
    
    
    class Basket{
     public:
      void add_item(const std::shared_ptr<Quote>& sale){
        items.insert(sale);
      }
      double total_receipt(std::ostream&) const;
     private:
      static bool compare(const std::shared_ptr<Quote>& lhs,
    		      const std::shared_ptr<Quote>& rhs){
        return lhs->isbn() < rhs->isbn();
      }
      std::multiset<std::shared_ptr<Quote>, decltype(compare)*>
        items{compare};
    };
    
    #endif
    
    

    Basket.cpp

    #include "Basket.h"
    
    double print_total(std::ostream& os,
    		   const Quote& item, size_t n);
    double Basket::total_receipt(std::ostream& os) const{
      double sum = 0.0;
      for(auto iter = items.cbegin();
          iter != items.cend();
          iter = items.upper_bound(*iter)){
        sum += print_total(os, **iter, items.count(*iter));
      }
      os << "Total Sale: " << sum << std::endl;
      return sum;
    }
    
    

    main.cpp

    #include "Quote3.h"
    #include "Basket.h"
    #include <vector>
    #include <iostream>
    
    double print_total(std::ostream& os,
    		   const Quote& item, size_t n){
      double ret = item.net_price(n);
      os << "ISBN: " << item.isbn()
         << " # sold: " << n << " total due: " << ret << std::endl;
      return ret;
    
    }
    
    int main(){
      Basket bsk;
      //bsk.add_item(std::make_shared<Quote>("01", 100));
      bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.total_receipt(std::cout);
    }
    
    

    执行结果1:

    ISBN: 01 # sold: 3 total due: 270
    Total Sale: 270
    

    把main函数改成下面:

    int main(){
      Basket bsk;
      bsk.add_item(std::make_shared<Quote>("01", 100));
      //bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.add_item(std::make_shared<Bulk_quote>("01", 100, 2, 0.1));
      bsk.total_receipt(std::cout);
    }
    

    执行结果2:

    ISBN: 01 # sold: 3 total due: 300
    Total Sale: 300
    

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

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

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

    本人微信:xiaoshitou5854

  • 相关阅读:
    链表的相关算法及应用(二)
    Hexo博客同时托管到github和coding
    Valine评论出现Code 403:访问被API域名白名单拒绝,请检查你的安全域名设置
    记一次Python爬虫入门
    基于SSM的个人博客
    JSTL和EL表达式遍历List数组
    bootstrap快速开发响应式页面
    标签随机文字颜色和字体大小的实现方法
    安卓Service和Broadcast实现简单的音乐播放器
    ListView设置OnItemClickListener点击没有反应
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/10218723.html
Copyright © 2011-2022 走看看