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;