#include <iostream>
using std::cin; using std::cout; using std::cerr; using std::endl;
using std::ostream;
#include <string>
using std::string;
class Quote{
public:
Quote() = default;
Quote(const string &book, double sales_price) :
bookNo(book), price(sales_price) {};
string isbn() const { return bookNo;}
//返回给定数量的书籍的销售总额
//派生类负责改写并使用不同的折扣计算算法
virtual double net_price(size_t n) const { return n * price;};
virtual ostream &debug(ostream &os) const {
os << "Quote::bookNo : " << bookNo << "\n"
<< "Quote::price :" << price << endl;
return os;
}
virtual ~Quote() { cout << "~Quote" << endl;} //对析构函数进行动态绑定
Quote(const Quote &rhs) : price(rhs.price), bookNo(rhs.bookNo) {
cout << "Quote(const Quote &rhs)" << endl;
} //拷贝构造函数
Quote(Quote &&rhs) noexcept : price(std::move(rhs.price)), bookNo(std::move(rhs.bookNo)){
cout << "Quote(Quote &&rhs)" << endl;
} //移动构造函数
Quote &operator=(const Quote &rhs){
price = rhs.price;
bookNo = rhs.bookNo;
cout << "operator=(const Quote &rhs)" << endl;
return *this;
} //拷贝赋值运算符
Quote &operator=(Quote &&rhs) noexcept {
price = std::move(rhs.price);
bookNo = std::move(rhs.bookNo);
cout << "operator=(Quote &&rhs)" << endl;
return *this;
} //移动赋值运算符
private:
string bookNo; //书籍的ISBN编号
protected:
double price = 0.0; //代表普通状态下不打折的价格
};
//计算并打印销售给定数量的某种书籍所得的费用
double print_total(ostream &os, const Quote &item, size_t n){
//根据传入item形参的对象类型调用Quote::net_price
//或者Bulk_quote::net_price
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() //调用Quote::isbn()
<< " # sold: " << n << " total due: " << ret << endl;
return ret;
}
//用于保存折扣值和购买量的类,派生类使用这些数据可以实现不同的价格策略
class Disc_quote : public Quote{
public:
Disc_quote() = default;
Disc_quote(const string &book, double price, size_t qty, double disc) :
Quote(book, price), quantity(qty), discount(disc) {};
double net_price(size_t) const = 0 ;
~Disc_quote() override { cout << "~Disc_quote()" << endl;}
Disc_quote(const Disc_quote &rhs) : Quote(rhs), quantity(rhs.quantity), discount(rhs.discount){
cout << "Disc_quote(const Disc_quote &rhs)" << endl;
} //拷贝构造函数
Disc_quote(Disc_quote &&rhs) noexcept : Quote(std::move(rhs)), quantity(std::move(rhs.quantity)),
discount(std::move(rhs.discount)) {
cout << "Disc_quote(Disc_quote &&rhs)" << endl;
} //移动构造函数
Disc_quote &operator=(const Disc_quote &rhs){
Quote::operator=(rhs);
quantity = rhs.quantity;
discount = rhs.discount;
cout << "operator=(const Disc_quote &rhs)" << endl;
return *this;
} //拷贝赋值运算符
Disc_quote &operator=(Disc_quote &&rhs) noexcept {
Quote::operator=(std::move(rhs));
quantity = std::move(rhs.quantity);
discount = std::move(rhs.discount);
cout << "operator=(Disc_quote &&rhs)" << endl;
return *this;
} //移动赋值运算符
protected:
size_t quantity = 0; //折扣适用的购买量
double discount = 0.0; //表示折扣的小数值
};
//当同一书籍的销售量超过某个值时启用折扣
//折扣的值是一个小于1的正的小数值,以此来降低正常销售价格
class Bulk_quote : public Disc_quote{ //Bulk_quote直接继承自Disc_quote,间接继承自Quote
public:
using Disc_quote::Disc_quote;
//覆盖基类的函数版本以实现基于大量购买的折扣政策
double net_price(size_t) const override;
};
//如果达到了购买书籍的某个最低限量值,就可以享受折扣价格了
double Bulk_quote::net_price(size_t cnt) const {
if (cnt > quantity)
return cnt * (1 - discount) * price;
else
return cnt * price;
}
class L_Bulk_quote : public Disc_quote{
public:
L_Bulk_quote() = default;
L_Bulk_quote(const string &book, double p, size_t qty, double disc) :
Disc_quote(book, p, qty, disc) {};
double net_price(size_t) const override;
};
double L_Bulk_quote::net_price(size_t cnt) const {
if (cnt <= quantity)
return cnt * (1 - discount) * price;
else
return (cnt - quantity) * price + quantity * (1 - discount) * price;
}
int main(){
Quote basic("978-7-121-15535-2", 128.00);
Bulk_quote bulk("978-7-121-15535-2", 128.00, 100, 0.3);
L_Bulk_quote l_bulk("978-7-121-15535-2", 128.00, 150, 0.3);
print_total(cout, basic, 20);
print_total(cout, bulk, 120);
print_total(cout, l_bulk, 200);
Quote basic_v1(basic);
Quote basic_v2 = basic_v1;
Quote basic_v3(std::move(basic_v2));
L_Bulk_quote l_bulk_v1(l_bulk);
L_Bulk_quote l_bulk_v2 = l_bulk_v1;
L_Bulk_quote l_bulk_v3(std::move(l_bulk_v2));
}