#include "stdafx.h"
#include <iostream>
#include <string>
#include <set>
using namespace std;
class Item_base {
public:
trueItem_base(const string &book = " ", double sales_price = 0.0, bool dbg = false)
truetrue: isbn(book), price(sales_price), is_debug(dbg) { }
truestring book() const { return isbn; }
truevirtual double net_price(size_t n) const { return n * price; }
true
truevirtual Item_base* clone() const { return new Item_base(*this); }
truevirtual void debug(ostream&) const;
truevirtual ~Item_base() { }
private:
truestring isbn;
protected:
truedouble price;
truebool is_debug;
};
void Item_base::debug(ostream &os = cout) const
{
trueif (!is_debug)
truetruereturn;
truecout << isbn << "\t" << price;
}
class Disc_item : public Item_base {
public:
trueDisc_item(const string &book = " ", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0, bool dbg = false)
truetrue: Item_base(book, sales_price, dbg), quantity(qty), discount(disc_rate) { }
true
truedouble net_price(size_t) const = 0;
truevoid debug(ostream&) const;
true~Disc_item() { }
protected:
truesize_t quantity;
truedouble discount;
};
void Disc_item::debug(ostream& os = cout) const
{
trueif (!is_debug)
truetruereturn;
trueItem_base::debug(os);
trueos << "\t" << quantity << "\t" << discount << endl;
}
class Lds_item : public Disc_item {
public:
trueLds_item(const string &book = " ", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0, bool dbg = false)
truetrue: Disc_item(book, sales_price, qty, disc_rate, dbg) { }
truedouble net_price(size_t) const;
trueLds_item* clone() const { return new Lds_item(*this); }
true~Lds_item() { }
};
double Lds_item::net_price(size_t cnt) const
{
trueif (cnt <= quantity)
truetruereturn cnt * (1 - discount) * price;
trueelse
truetruereturn cnt * price - quantity * discount *price;
}
class Bulk_item : public Disc_item {
public:
trueBulk_item(const string &book = " ", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0, bool dbg = false)
truetrue: Disc_item(book, sales_price, qty, disc_rate, dbg) { }
truedouble net_price(size_t) const;
trueBulk_item* clone() const { return new Bulk_item(*this); }
true~Bulk_item() { }
};
double Bulk_item::net_price(size_t cnt) const
{
trueif (cnt >= quantity)
truetruereturn cnt * (1 - discount) * price;
trueelse
truetruereturn cnt * price;
}
class Sales_item {
public:
trueSales_item() : p(0), use(new size_t(1)) { }
trueSales_item(const Item_base &item) : p(item.clone()), use(new size_t(1)) { }
trueSales_item(const Sales_item &i) : p(i.p), use(i.use) { ++*use; }
true~Sales_item() { decr_use(); }
trueSales_item& operator=(const Sales_item&);
true
true
trueconst Item_base* operator->() const { if (p) return p; else throw logic_error("unbound Sales_item"); }
trueconst Item_base& operator*() const { if (p) return *p; else throw logic_error("unbound Sales_item"); }
private:
trueItem_base *p;
truesize_t *use;
truevoid decr_use()
truetrue{ if (--*use == 0) { delete p; delete use; } }
};
Sales_item& Sales_item::operator=(const Sales_item &rhs)
{
true++*rhs.use;
truedecr_use();
truep = rhs.p;
trueuse = rhs.use;
truereturn *this;
}
inline bool compare(const Sales_item &lhs, const Sales_item &rhs)
{
truereturn lhs->book() < rhs->book();
}
class Basket {
true
true
truetypedef bool (*Comp)(const Sales_item&, const Sales_item&);
public:
truetypedef multiset<Sales_item, Comp> set_type;
truetypedef set_type::size_type size_type;
truetypedef set_type::const_iterator const_iter;
trueBasket() : items(compare) { }
truevoid add_item(const Sales_item &item) { items.insert(item); }
truesize_type size(const Sales_item &i) const { return items.count(i); }
truedouble total() const;
private:
truemultiset<Sales_item, Comp> items;
};
double Basket::total() const
{
truedouble sum = 0.0;
truefor (const_iter iter = items.begin(); iter != items.end(); iter = items.upper_bound(*iter))
truetruesum += (*iter)->net_price(items.count(*iter));
truereturn sum;
}
void print_total(const Item_base &item, size_t n)
{
truecout << "ISBN: " << item.book() << "\tnumber sold: " << n << "\ttotal price: " << item.net_price(n) << endl;
}
int main()
{
trueSales_item item1(Bulk_item("7-115-14554-7", 99, 20, 0.2));
trueSales_item item2(Item_base("7-115-14554-8", 39));
trueSales_item item3(Lds_item("7-115-14554-9", 50, 200, 0.2));
trueSales_item item4(Bulk_item("7-115-14554-7", 99, 20, 0.2));
trueBasket basket;
truebasket.add_item(item1);
truebasket.add_item(item2);
truebasket.add_item(item3);
truebasket.add_item(item4);
truecout << basket.total() << endl;
truesystem("pause");
truereturn 0;
}