#pragma once
#include <iostream>
#include <set>
class Basket
{
public:
//Basket使用合成的默认构造函数和拷贝控制成员
void add_item(const std::shared_ptr<Quote>& sale) {
items.insert(sale);
}
//由于上面的添加元素函数,用户仍然必须处理动态内存,进而改正
//使用虚函数解决类型识别问题
void add_item(const Quote& sale) {
items.insert(std::shared_ptr<Quote>(sale.clone()));
}
void add_item(Quote&& sale) {
items.insert(std::shared_ptr<Quote>(std::move(sale).clone()));//尽管sale是一个右值引用类型,但实际上sale本身是一个左值。(变量为左值)
}
//打印每本书的总价和购物篮中所有书的总价
double total_receipt(std::ostream&) const;
private:
//该函数用于比较shared_ptr,multiset成员会用到它
static bool compare(const std::shared_ptr<Quote>& lhs, const std::shared_ptr<Quote>& rhs) {
return lhs->isbn() < rhs->isbn();
}
//multiset保存同一本书的多个报价,按照compare成员排序
//shared_ptr没有定义小于运算符,必须提供自己的比较运算符
std::multiset<std::shared_ptr<Quote>, decltype(compare)*> items{compare};//初始化items并令其使用compare函数
};
class Quote {
public:
//该虚函数返回当前对象的一份动态分配的拷贝
virtual Quote* clone() const& {
return new Quote(*this);
}
virtual Quote* clone()&& {
return new Quote(std::move(*this));
}
};
class Bule_quote : public Quote {
public:
//该虚函数返回当前对象的一份动态分配的拷贝
virtual Bule_quote* clone() const& {
return new Bule_quote(*this);
}
virtual Bule_quote* clone()&& {
return new Bule_quote(std::move(*this));
}
};
#include "Basket.h"
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)) {//upper_bound返回一个第一个大于*iter元素的迭代器
sum += print_total(os, **iter, items.count(*iter));
}
os << "Total Sale: " << sum << std::endl;
return sum;
}