15.28
#include <iostream>
#include <vector>
#include <memory>
#include "Quote.h"
using namespace std;
int main()
{
Bulk_quote item("a2", 7.7, 10, 0.2);
vector<Quote> qv;
qv.push_back(item);
double sum1 = 0.0;
for (auto &q : qv)
sum1 += q.net_price(20);
cout << sum1 << endl;
vector<shared_ptr<Quote>> pitem;
pitem.push_back(make_shared<Bulk_quote>(item));
double sum2 = 0.0;
for (auto &q : pitem)
sum2 += q->net_price(20);
cout << sum2 << endl;
return 0;
}
15.29 见上题。用vector<Quote>与用vector<shared_ptr<Quote>>结果不同,前者仍然使用Quote类中的net_price函数计算,后者用Bulk_quote的net_price函数。
15.30 修改Quote.h文件,增加clone函数:
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
using namespace std;
class Quote {
public:
Quote() = default;
Quote(const string &book, double sales_price):
bookNo(book), price(sales_price) { }
Quote(const Quote &q):
bookNo(q.bookNo), price(q.price) { }
Quote(Quote &&q):
bookNo(std::move(q.bookNo)), price(std::move(q.price)) { }
Quote& operator=(const Quote&);
Quote& operator=(Quote &&q);
string isbn() const { return bookNo; };
virtual double net_price(size_t n) const
{ return n * price; }
virtual void debug() { cout << "bookNo: "<< bookNo << " price: " << price << endl; }
virtual ~Quote() = default;
virtual Quote* clone() const & { return new Quote(*this); }
virtual Quote* clone() && { return new Quote(std::move(*this)); };
private:
string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote: public Quote {
public:
Bulk_quote() = default;
Bulk_quote(const string &book, double p, size_t qty, double disc):
Quote(book, p), min_qty(qty), discount(disc) { }
Bulk_quote(const Bulk_quote &b):
Quote(b), min_qty(b.min_qty), discount(b.discount) { }
Bulk_quote(Bulk_quote &&b):
Quote(std::move(b)), min_qty(std::move(b.min_qty)), discount(std::move(b.discount)) { }
Bulk_quote& operator=(const Bulk_quote&);
Bulk_quote& operator=(Bulk_quote&&);
~Bulk_quote() = default;
void debug() override { Quote::debug(); cout << "min_qty= " << min_qty << " discount= " <<
discount << endl; }
double net_price(size_t) const override;
Bulk_quote* clone() const & { return new Bulk_quote(*this); }
Bulk_quote* clone() && { return new Bulk_quote(std::move(*this)); }
private:
size_t min_qty = 0;
double discount = 0.0;
};
double print_total(ostream &os, const Quote &item, size_t n);
#endif
Basket.h文件:
#ifndef BASKET_H
#define BASKET_H
#include <memory>
#include <set>
#include "Quote.h"
using namespace std;
class Basket {
public:
void add_item(const Quote &sale)
{ items.insert(shared_ptr<Quote>(sale.clone())); }
double total_receipt(ostream&) const;
private:
static bool compare(const shared_ptr<Quote> &lhs, const shared_ptr<Quote> &rhs)
{ return lhs->isbn() < rhs->isbn(); }
multiset<shared_ptr<Quote>, decltype(compare)*> items{compare};
};
double Basket::total_receipt(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));
cout << "Total Sale: " << sum << endl;
return sum;
}
#endif
测试主程序:
#include <iostream>
#include <vector>
#include <memory>
#include "Quote.h"
#include "Basket.h"
using namespace std;
int main()
{
Quote q1("a1", 8.9);
Bulk_quote q2("a2", 7.7, 10, 0.2);
Basket b;
for (auto i = 0; i < 10; ++i)
b.add_item(q1);
for (auto j = 0; j < 20; ++j)
b.add_item(q2);
b.total_receipt(cout);
return 0;
}