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

原文地址:https://www.cnblogs.com/xiaoshiwang/p/10218723.html